| |
|
开发:
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++》笔记 第二章 构造、析构和赋值 |
第二章、构造、析构和赋值五、了解C++默默编写并调用了哪些函数??????? empty class(空类),编译器会为他声明一个copy构造函数、copy assignment操作符和一个析构函数。此外如果没有声明任何构造函数,编译器会声明一个default构造函数。所有这些函数都是public且inline。 ????????
??????? 只有但这些函数被调用,它们才会被编译器创建出来。下面代码将会将上面的函数创建出来
??????? 如果父类将copy assignment操作符声明为private,编译器将拒绝为其子类生成一个copy assignment 操作符。 ??????? 注意: ??????? 编译器可以为class创建default构造函数、copy构造函数、copy assignment操作符,以及析构函数。 六、若不想使用编译器自动生成的函数,就应该明确拒绝。??????? 将不想使用的copy函数和copy assignment函数声明为private而且没有定义。或者使用一个基类阻止copying动作。 ??????? 问:为什么不使用delete。 七、为多态基类声明virtual析构函数??????? 当derived class对象经由一个base class指针被删除,而该base class呆着一个Non-virtual析构函数,其结果未有定义--实际执行时通常发生的是对象的derived成分没有被销毁。于是造成一个局部销毁现象,形成资源泄漏。 ??????? 消除这个问题:给base class一个virtual析构函数。任何class只要带有virtual函数都几乎确定应该也有一个virtual析构函数。 ??????? 如果class不含virtual函数,如果将其析构函数生命为virtual。会导致占用更多的内存。因为要实现virtual函数,对象会产生一个vptr(virtual table pointer)指针。vptr指向一个由函数指针构造成的数组,成为vtbl(virtual table pointer),每一个带有virtual函数的class都有一个相应的vtbl。当对象调用某一个virtual函数。实际被调用的函数取决于对象vptr所指向的那个vtbl。 ??????? 如果class内含virtual函数,其对象的体积会增加。 ??????? 析构函数的运作方式:最深层派生的那个class其析构函数最先被调用,然后是其每一个base class的析构函数被调用。 ??????? 注意: ??????? polymorphic(带多态性质的)base classes应该声明一个virtual析构函数。如果class带有任何virtual函数,它就应该拥有一个virtual析构函数 ??????? classes的设计目的如果不是作为base classes使用,或不是为了具备多态性(polymorphically),就不应该声明virtual析构函数 八、别让异常逃离析构函数??????? 在析构函数中突出异常,可能导致不明确行为。 ??????? 1、如果close抛出异常就结束程序,通常通过调用abort完成。 ??????? 2、吞下因调用close而发生的异常 ??????? 注意: ??????? 1、析构函数绝对不要突出异常,如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下它们或结束程序 ??????? 2、如果客户需要对某个操作函数运行期间抛出的异常做出反应,那么class应该提供一个普通函数(而非在析构函数中)执行该操作。 九、绝不在构造和行析构过程中调用virtual函数??????? derived class对象内的base class成分会在derived class自身成分被构造前先构造出来。base class构造期间virtual函数绝不会下降到derived classes阶层。在base class构造期间,virtual函数不是virtual函数。 ??????? 因为base class构造函数的执行更早于derived class构造函数,当base构造函数执行时,derived classes的成员变量尚未初始化,如果此期间调用virtual函数下降至derived classes阶层,因为这些Local成员变量尚未初始化,这回导致对象内部尚未初始化的风险。 ??????? 在derived class对象的base class构造期间,对象的类型是Base class而不是Derived class。不只virtual函数会被编译器解析至base class,若使用运行期类型信息,也会把对象视为base class类型。对象在derived class构造函数开始执行前不会成为一个derived class对象。 ??????? 避免代码重复,将共同的初始化代码放进一个初始化函数init内。 ??????? 因为无法使用virtual函数从base classes向下调用,在构造期间,你可以藉由令derived classes将必要的构造信息向上传递至Base class构造函数。替换之而加以弥补。 ??????? 注意:在构造和析构期间不要调用virtual函数,因为这类调用从不下降至derived class 十、令operator=返回一个reference to? *this??????? 在赋值过程中,可以将它携程连锁形式:
??????? 这里15先被赋值给z,然后其结果(更新后的z)再被赋值给y,然后再被赋值给x。 ??????? 为了实现“连锁赋值”,赋值操作符必须返回一个reference指向操作符的左侧实参。
??????? 这个协议不仅适用于以上的标准赋值形式,也适用于所有赋值相关运算。如+=,-=,*=等等。 ??????? 注意:令赋值(assignment)操作符返回一个reference to *this。 十一、在operator=中处理自我赋值??????? 别名:有一个以上的方法指称某对象,一般而言如果某段代码操作pointers或references而它们被用来指向多个相同类型的对象,就要考虑这些对象是否为同一个。实际上两个对象只要来自同一个继承体系,它们甚至不需要声明为相同类型就可能造成别名。因为一个Base class的ference或Pointer可以指向一个derived class对象。 ??????? 如果阐释自行管理资源(打算写一个用于资源管理的class)。可能掉进“在停止使用资源之前意外释放它”的陷阱。 ??????? 传统做法:在operator=最前面做认同测试,达到自我赋值的检验目的。
??????? 但是如果new Bitmap导致异常,Wdiget最终会吃持有一个指针指向一块被删除的Bitmap。其实精心安排语句也可以做到。只需要注意复制pb所指东西之前别删除pb就好。 ?
??????? 替代方案:使用copy and swap技术。
??????? 注意: ??????? 1、确保当对象自我赋值时Operator=有良好欣慰。其中技术包括比较来源对象和目标对象的地址、精心周到的语句顺序,以及copy and swap。 ??????? 2、确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确。 十二、赋值对象时勿忘其每一个成分??????? 当编写一个copying函数请确保: ??????? 1、复制所有Local成员变量 ??????? 2、调用所有base classes内适当的copying函数。 ??????? 不应使用copy assignment操作符调用copy构造函数,同样也不许copy构造函数调用copy assignment操作符。如果copying函数中有相近的代码,建立一个新的成员函数给两者调用。这个函数通常为private并被命名为init。 ??????? 注意: ??????? 1、copying函数应确保赋值对象内的“所有成员变量”即所有“base class成分” ??????? 2、不要尝试以某个copying函数实现另一个copying函数。应该将共同技能放进第三个函数中,并由两个copying函数共同调用。 |
|
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 7:18:14- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |