【足迹C++primer】19、构造函数再探
来源:互联网 发布:知乎必须用手机注册吗 编辑:程序博客网 时间:2024/06/05 18:20
构造函数再探
构造函数初始值列表
Sales_data::Sales_data(const string &s, unsigned cnt, double price) { bookNo=s; units_sold=cnt; revenue=cnt*price; }
这个构造函数和这个效果是一样的
Sales_data(const std::string &s, unsigned n, double p): bookNo(s),units_sold(n),revenue(p*n){}
构造函数的初始值有时必不可少
当成员是const类型或者是引用的时候就必须将其初始化,或者是类类型的时候,且该类没有构造函数定义的时候,那么也要将其初始化
class ConstRef{public: ConstRef(int ii);private: int i; const int ci; int &ri;};//错误的构造函数的初始化ConstRef::ConstRef(int ii){ //赋值 i=ii; //正确 ci=ii; //错误:不能给const赋值 ri=i; //错误:ri没被初始化}//正确的打开方式ConstRef::ConstRef(int ii):i(ii),ci(ii),ri(i){ }
建议:使用构造函数初始值(就是上面的正确打开方式)
在很多类中,初始化和赋值的区别事关底层效率问题,前者(就是上面的正确打开方式)直接初始化,后者(赋值错误打开方式)先初始化后赋值。
成员初始化的顺序
成员初始化的顺序和他们在类定义中的出现顺序一致。
class X{ int i; //先被初始化 int j; //后被初始化public: X(int val):j(val),i(j){}};
<span style="font-weight: normal;">class Sales_data{ //为Sales_data的非成员函数所做的友元声明 friend Sales_data add(const Sales_data&, const Sales_data&); friend std::istream &read(std::istream&, Sales_data&); friend std::ostream &print(std::ostream&, const Sales_data&);public: //增加了访问说明符 //构造函数 Sales_data() = default; Sales_data(const std::string &s, unsigned n, double p): bookNo(s),units_sold(n),revenue(p*n){} Sales_data(const std::string s="11"):bookNo(s){cout<<"xxxx"<<endl;} Sales_data(std::istream &is){read(is, *this);} /* Sales_data::Sales_data(const string &s, unsigned cnt, double price) { bookNo=s; units_sold=cnt; revenue=cnt*price; }*/ //普通成员函数 std::string isbn()const {return bookNo;} Sales_data &combine(const Sales_data&);private: double avg_price() const { return units_sold ? revenue/units_sold : 0; } std::string bookNo; unsigned units_sold=0; double revenue=0.0;};//Sales_data接口的非成员组成部分的声明Sales_data add(const Sales_data&, const Sales_data&);std::istream &read(std::istream&, Sales_data&);std::ostream &print(std::ostream&, const Sales_data&);int main(){ Sales_data next(); Sales_data last("9-999-99999-9"); return 0;}</span>
这里面,main函数里面一个调用的defalut一个调用的是<span style="font-weight: normal; ">Sales_data(const std::string s="11"):bookNo(s){cout<<"xxxx"<<endl;}</span>
委托构造函数
//构造函数 Sales_data(const std::string &s, unsigned n, double p): bookNo(s),units_sold(n),revenue(p*n){} //其余构造函数都委托给另外构造函数 Sales_date():Sales_data("",0,0) {} Sales_data(std::string s):Sales_data(s,0,0) {} Seles_data(std::istream &is):Sales_data() {read(is, *this);}
聚合类
聚合类使得用户可以直接访问其成员,并且具有特殊的初始化语法形式。
一般使用struct定义的类就是聚合类
并且声明一个类的对象的时候,初始值顺序必须和声明顺序一致
字面值常量类
class Debug{public: constexpr Debug(bool b=true):hw(b),io(b),other(b) {} constexpr Debug(bool h, bool i, bool o):hw(h),io(i),other(o) {} constexpr bool any() {return hw || io || other;} void set_io(bool b) {io=b;} void set_hw(bool b) {hw=b;} void set_other(bool b) {other=b;}private: bool hw; //硬件错误 bool io; //IO错误 bool other; //其他错误};
使用了constexpr的构造函数意味着1、不能有返回值2、拥有唯一可执行的语句返回语句。。。。综合就是函数体应该是空的。
这里我觉得书上这样翻译纯属扯淡,自相矛盾,应该看英文版本的!!!可惜my English is very pool!!
PS:坚持不懈,不在多,而在精华,但是有时候会给一点糟粕,那是因为时间过得太快,不能再那些没必要的小事上浪费时间,但是碰到自己不熟悉的,不清楚的那么你就得好好看看一看,停下脚步认真的学一学了!!!!
0 0
- 【足迹C++primer】19、构造函数再探
- 【足迹C++primer】54、继承类的范围,构造函数和拷贝控制
- 【足迹C++primer】14、函数匹配、函数指针
- c++primer之类(构造函数再探)
- 【足迹C++primer】48、函数引用操作符
- 【足迹C++primer】52、转换和继承,虚函数
- 【足迹C++primer】表达式求值
- 【足迹C++primer】33、再探迭代器
- 【足迹C++ primer】10.函数基础
- 【足迹C++ primer】12、函数重载
- 【足迹C++primer】15、定义抽象数据类型
- 【足迹C++primer】21、IO类
- 【足迹C++primer】22、文件输入输出
- 【足迹C++primer】23、string流
- 【足迹C++primer】24、顺序容器概述
- 【足迹C++primer】25、容器库概览
- 【足迹C++primer】26、顺序容器操作
- 【足迹C++primer】29、容器适配器
- poj2828Buy Tickets
- easy to understander characterise resistent
- LeetCode: Binary Tree Level Order Traversal II [107]
- Android输入法扩展之远程输入法
- 升了osx10.10后cocoapods用不了的解决方法
- 【足迹C++primer】19、构造函数再探
- Android自动化测试初探(一): 捕获Activity上的Element
- 自学第六天
- LeetCode: Convert Sorted Array to Binary Search Tree [108]
- LeetCode: Convert Sorted List to Binary Search Tree [109]
- Linux环境编程之IPC进程间通信(三):FIFO
- LeetCode: Balanced Binary Tree [110]
- LeetCode: Minimum Depth of Binary Tree [111]
- 保存,读取,状态切换