【c++ primer, 5e】构造函数 & 拷贝、赋值和析构
【构造函数】
1、构造器就是创建对象时被调用的代码。
2、如果没有自定义构造器,那么编译器将自动合成一个默认的无参构造器。
3、自定义的构造器不允许加const,所创建const的对象只有在构造器代码执行完后,才被赋予const性质。
4、如果自定义了构造器,那么默认的构造器将无效化,可以理解为自定义内容覆盖了默认的内容。—— “要么什么都不做,要么全部都交给你来做。”
5、构造函数使用类内初始值并不是一个坏选择。
6、default。(在练习中体现)
7、构造函数初始值列表。(在练习中体现)
练习
7.11
ps:定义在类内的函数默认为内联的!类外的不是。(内联函数可以提高性能,那么,为什么不把所有函数都定义成内联函数呢?内联函数的优缺点)
#include <iostream>
#include <string>
using namespace std; // Sales_data.h
struct Sales_data {
// 新增的构造函数
Sales_data() = default; // 完全等同于合成默认构造器,不写就没有!!!
Sales_data(const string &s): bookNo(s) {} // “:”到“}”之间为构造函数初始值列表
Sales_data(const string &s, unsigned n, double p): bookNo(s), units_sold(n), revenue(p*n) {}
Sales_data(istream&);
// public部分,对象看起来是怎么样的。
std::string isbn() const { return bookNo; } // inline function
Sales_data& combine(const Sales_data&);
double avg_price() const;
// private部分,数据成员。
std::string bookNo;
unsigned units_sold = ;
double revenue = 0.0;
};
// Sales_data的非成员接口函数
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream &print(std::ostream&, const Sales_data&);
std::istream &read(std::istream&, Sales_data&); // Sales_data.cpp
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
istream &read(istream &is, Sales_data &item)
{
double price = ;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
double Sales_data::avg_price() const {
if (units_sold)
return revenue/units_sold;
else
return ;
}
Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
Sales_data sum = lhs;
sum.combine(rhs);
return sum;
}
Sales_data::Sales_data(istream &is)
{
read(is, *this);
} // main.cpp
int main()
{
Sales_data data1; // default
Sales_data data2("ISOD233");
Sales_data data3("ISOD233", , 22.5);
Sales_data data4(cin); print(cout, data1) << endl;
print(cout, data2) << endl;
print(cout, data3) << endl;
print(cout, data4) << endl;
/* output:
0 0 0
ISOD233 0 0 0
ISOD233 3 67.5 22.5
DASD23 4 88 22
*/
return ;
}
7.12
就知道这题有坑。
prog1.cpp: In constructor 'Sales_data::Sales_data(std::istream&)':
prog1.cpp::: error: 'read' was not declared in this scope
read(is, *this);
翻了一下收藏的博客,发现这道题要用友元函数(下一小节)。
7.13
参考(不会写)。
Sales_data total(cin);
if (total.units_sold > ) {
Sales_data trans;
while (read(cin, trans)) {
if (total.isbn() == trans.isbn())
total.combine(trans);
else {
print(cout, total) << endl;
total = trans;
}
}
print(cout, total) << endl;
} else {
cerr << "No data?!" << endl;
}
7.14
是这样吗?
Sales_data()
{
units_sold = ;
revenue = 0.0;
}
7.15
测试无误。
// constructor
Person() = default;
Person(const string &name): name(name) {}
Person(const string &name, const string &address): name(name), address(address) {}
Person(istream&);
Person::Person(istream &is)
{
read(is, *this);
}
【拷贝、赋值和析构】
如果我们不主动定义这些操作,那么编译器将会替我们合成它们。
默认的析构函数将会在语句块结束时被调用,销毁局部变量。
某些类(管理动态内存的类)不能依赖于合成的版本,因此有时候不得不定义这些函数。
【c++ primer, 5e】构造函数 & 拷贝、赋值和析构的更多相关文章
- [c++基础]3/5原则--拷贝构造函数+拷贝赋值操作符
/* * main.cpp * * Created on: Apr 7, 2016 * Author: lizhen */ #include <iostream> #include &qu ...
- 构造函数和初始化表、this指针与常函数、析构函数、拷贝构造与拷贝赋值(day05)
十四 构造函数和初始化表 ... 初始化表 )语法形式 class 类名{ 类名(形参表):成员变量1(初值),...{} }; )必须要使用初始化表的场景 -->如果有类 类型的成员变量,而该 ...
- C++类中函数(构造函数、析构函数、拷贝构造函数、赋值构造函数)
[1]为什么空类可以创建对象呢? 示例代码如下: #include <iostream> using namespace std; class Empty { }; void main() ...
- C++中的构造函数,拷贝构造函数和赋值运算
关于C++中的构造函数,拷贝构造函数和赋值运算,以前看过一篇<高质量C++/C编程指南>的文章中介绍的很清楚,网上能搜索到,如果想详细了解这方面的知识可以参看一下这篇文章. 常见的给对象赋 ...
- 关于C++中的拷贝构造函数和赋值函数
如果类定义的数据成员中存在指针或引用,那么最好重载这两个函数. 1. 定义 拷贝构造函数的定义格式:构造函数名(const 源类名& 引用对象形参名){} 赋值函数定义格式:源类名 & ...
- C++雾中风景6:拷贝构造函数与赋值函数
在进行C++类编写的过程之中,通常会涉及到类的拷贝构造函数与类的赋值函数.初涉类编写的代码,对于两类函数的用法一直是挺让人困惑的内容.这篇文章我们会详细来梳理拷贝构造函数与赋值函数的区别. 1.调用了 ...
- C++中:默认构造函数、析构函数、拷贝构造函数和赋值函数——转
对于一个空类,编译器默认产生4个成员函数:默认构造函数.析构函数.拷贝构造函数和赋值函数.1.构造函数:构造函数是一种特殊的类成员,是当创建一个类的时候,它被调用来对类的数据成员进行初始化和分配内存. ...
- 【C++】拷贝构造函数和赋值符函数
在C++中,调用拷贝构造函数有三种情况: 1.一个对象作为函数参数,以值传递的方式传入函数体. 2.一个对象作为函数返回值,以值传递的方式从函数返回. 3.一个对象用于给另外一个对象进行初始化(复制初 ...
- CPP_类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数
类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数 // person.h #ifndef _PERSON_H_ #define _PERSON_H_ class Person{ public : ...
随机推荐
- 《C++ Primer Plus》第5章 循环和关系表达式 学习笔记
C++提供了3种循环: for 循环. while 循环 和 do while 循环 .如果循环测试条件为 true 或非零,则循环将重复执行一组指令: 如果测试条件为 false 或 0 , 则结束 ...
- 第一次广搜!HDU1548--A Strange Lift
一上来看见题目就用了深搜(因为只会深搜)果断内存超限(据说时间也会超限)无奈只好开始用广搜 其实广搜的思路和深搜有很多类似的地方 不过实现的过程中用到了队列 因此有点难以理解(好吧我个人认为) 这题是 ...
- 【黑金原创教程】【TimeQuest】【第二章】TimeQuest模型角色,网表概念,时序报告
声明:本文为黑金动力社区(http://www.heijin.org)原创教程,如需转载请注明出处,谢谢! 黑金动力社区2013年原创教程连载计划: http://www.cnblogs.com/al ...
- Python全栈day21-22-23(模块)
一,python的模块 Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块让你能够有逻辑地组织你的 Python ...
- 2017 Multi-University Training Contest - Team 4——HDU6069&&Counting Divisors
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6069 题目意思:首先解释一下d[n]这个函数表示n有多少个因子,百度一下可以知道这个函数是一个非完全积 ...
- MapReduce分析流量汇总
一.MapReduce编程规范 一.MapReduce编程规范 用户编写mr程序主要分为三个部分:Mapper,Reducer,Driver 1.Mapper阶段 (1)用户自定义Mapper类 要继 ...
- Guess Your Way Out! II---cf 558D (区间覆盖,c++STL map 的使用)
题目链接:http://codeforces.com/contest/558/problem/D 题意就是有一个二叉树高度为 h ,人站在根节点上,现在要走出去,出口在叶子节点上,有 q 条信息,每条 ...
- riemann的安装和使用
Riemann monitors distributed systems. 具体介绍就不多说了,一个分布式的监控系统.可以接收各种event上报,然后通过强大的脚本和插件,展示曲线,柱状,饼图等来对系 ...
- 如何让thrift0.9.2 在macos上面编译通过?
为将来跨语言通信预研,选择了thrift来试试.结果在mac os上面安装遇到种种困难,不知道是我选择方法错误还是咋的,不管怎样,总算是编译过去了. 首先,我们来参考官网的安装步骤:https://t ...
- 从CPU/OS到虚拟机和云计算
从CPU/OS到虚拟机和云计算 作者:张冬 关于软硬件谁为主导这个话题,套用一句谚语就是三十年河东三十年河西.风水轮流转.软件和硬件一定是相互促进.相互拆台又相互搭台的. ...