| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> <<Effective C++>> 读书笔记 -> 正文阅读 |
|
[C++知识库]<<Effective C++>> 读书笔记 |
条款04:确定对象被使用前已先被初始化
在某些语境下,x被保证被初始化为0,但某些语境却不保证,现在,我们终于有了一些规则 1.对于无任何成员的内置类型,必须手工完成初始化
2.对于内置类型以外的任何其他东西,初始化落在构造函数身上,规则是:确保每一个构造函数都将对象的每一个成员初始化 对于初始化,很多人都把赋值与之混淆,观察以下代码
第二版的构造函数(用初始化列表)通常比第一个构造函数(赋值操作)效率更高,由于赋值那个版本会先调用默认构造函数(string类的和int类的)为StuName,StuAddress,StuPhones设初值,然后再对它们赋值(string类的copy赋值和int类的copy赋值).使用初始化列表的那个版本避免了这个问题,因为初始化列表里的实参,会为各个成员变量进行拷贝构造(string类的和int类的),例如,本例中的StuName以name为初值进行copy构造,StuAddress以address为初值进行copy构造,StuPhones以phones为初值进行copy构造. 相比调用默认构造然后调用拷贝赋值,只调用一次copy构造函数的效率是比较高的. 如果面对成员变量属于内置类型,(初始化与赋值的成本相同),也一定要设初始化列表来初始化(有些情况还是可以不用的),如果成员变量是const或references,它们就必须要初始化列表来初始化,因为const类型无法被赋值,而references类型一定要有初值. 如果class内有很多个构造函数,根据规则2,每个构造函数又必须对每个成员初始化,这样会导致很多的重复.这种情况下可以灵活的在初始化列表遗漏那些"赋值表现得像初始化一样好"的成员变量,例如一些int,double,bool等内置类型,改用它们的赋值操作,然后将这些赋值操作放在某个函数(一般是private,因为不需要外部调用而且经常在构造函数里调用)供所有的构造函数调用. C++对于"成员初始化次序"有着十分固定的规则:base classes总是更早与derived class初始化(想想也是,没有父类哪来的子类,值得一提的是,析构函数则是从子类开始),class的成员变量则总是以其声明的次序来被初始化. 注:此条款后续内容还会更新(作者太菜,看不是很懂,等境界到了再回头补充) 谨记: 1.为内置型对象进行手工初始化,因为C++不保证初始化它们 2.构造函数最好使用初始化列表,而不要在构造函数本体内使用赋值操作.初始化列表列出的成员变量,其排列次序应该和它们在class的声明中的次序一致 3.为免除"跨编译单元之初始化次序"问题,请以local static对象替换non-local static对象 条款05:了解C++默默编写并调用哪些函数我们知道,在类里没有声明构造函数,析构函数,拷贝构造函数,拷贝赋值函数时,编译器就会为该类声明一个编译器版本的,并且这些函数都是public且inline的,就像以下代码
值得注意的是,如果class没有三大函数时(析构函数,copy构造函数,copy赋值函数),编译器就会声明它们,而当调用了它们之后,编译器才会生成它们.而且,编译器声明的析构函数是non-virtual函数,除非这个class的base class有virtual析构函数. 至于copy构造函数和copy赋值函数,编译器创建的版本只是单纯地将来源对象的每一个non-static成员变量拷贝到目标对象,记得在课堂上,老师也强调过这两个默认函数,执行的只是浅拷贝,需要注意类内有没有指针类型,如果有指针的话,就必须自己写这两个函数(当然了,析构函数也要写),目的是为了防止悬空指针的出现(写析构函数是为了防止内存泄漏). 对于copy构造函数,编译器只对每一个bits进行拷贝,比较简单.如果你未提供,编译器总会给你一个默认的版本. 而对于copy赋值函数,编译器有时候压根就不给你默认定义copy赋值函数,我们来看以下代码
在主函数测试以下代码
?编译器对p = s报错,原因是编译器没有为我们生成拷贝赋值函数 事实上,当你打算在一个"类内含reference成员或者const成员"的class内支持赋值操作,就必须自己定义一个copy赋值函数(写这个的时候注意对象的自我赋值哦),编译器是不会为你生成的,原因很简单,我们都知道,引用就是一个变量的别名,一旦指定一个变量后,便不能再指定别的了(指针则可以,形象来说,指针比较花心,引用比较专情hh),同样的,const类型也不能更改,那就拿p = s来说,p内含有一个引用或者const成员,C++都不允许改变它.所以编译器无法为你提供copy赋值函数. 谨记: 1.编译器可以暗自为class创建default构造函数,copy构造函数,copy assignment操作符,以及析构函数. 2.编译器不会提供"类内含reference成员或者const成员"的class拷贝赋值操作符 |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 5:58:51- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |