C++-----深度探索C++对象模型-第五章-构造、析构、拷贝语意学(一)

1、拥有纯虚函数的基类不可能有实例对象。

2、一般来说,类的数据成员应该被初始化,并且只在构造函数中或类的其他成员函数中指定初值,其他操作都将破坏封装特性。

3、C++中,纯虚函数是可以定义和调用的,但是只能被静态的调用,不能经过虚拟机制来调用。

4、不要将虚析构函数定义为纯虚函数,定义为虚函数比较好。因为在每一个派生类的析构函数都会被编译器加以扩张,以静态调用的方式调用其每一个虚基类以及上一层的基类的析构函数,因此只要缺乏任何一个基类析构函数的定义就会导致链接失败。

5、不将函数声明为const,意味着函数不能获得一个const 的指针或引用,如果声明为const,就不能修改任何一个数据成员。

6、一般来说,对象有三种产生方式: 

    1)global内存配置,全局对象的生命周期是和整个程序的生命周期相同的。

    2)local内存配置,局部对象的生命周期是程序结束之前析构函数调用时结束。

    3)heap内存配置(new出来的对象),堆上的对象生命周期是从new到delete。

7、全局对象会在程序起始处调用构造函数,在程序的exit()出调用析构函数(在main函数结束前由编译器产生),事实上有些类的没有必要的构造函数和析构函数要不是在实际情况下没有被定义出来,要不是没有调用。在C++中,全局对象视为完全定义,所有的全局对象都以初始化过的数据来对待(这和C是不同的,但是其还是会在.bss段)。

8、C++的类中,如果只定义了数据,那么其就是一个POD类型,这种情况下没有析构函数和构造函数的定义与调用。其数据赋值操作其实是像C那样的位搬移。

9、当C++的类中出现了显式的构造函数,有了public和private接口后,其大小也没有改变,因为没有虚函数机制。

10、如果要将类中的所有成员都设定常量初值,那么用列表初始化效率更高。如果用一个函数初始化,那么当函数激活放入堆栈时,初始化列表的常量可以被放进内存了。

11、显式初始化带来三个缺点:

    1)只有当数据成员是public时,才奏效。

    2)只能指定常量,因为它们在编译时期就可以被评估求值。

    3)由于编译器没有自动施行,所以初始化失败可能性变高。

对于显式成员初始化列表的效率优点来说,平衡软件工程上的缺点是不现实的,只有在一些特殊情况下使用显式成员列表初始化效率会比inline 构造函数好得多,特别是对全局对象而言。

12、无用的默认构造函数、拷贝构造函数、析构函数实际上编译器并没有产生他们。

13、虚函数的出现,由于虚函数表,每一个对象要付出虚函数指针的代价,32位机器即4字节。

14、当一个类出现虚函数时,编译器会对我们的类产生膨胀作用:

    1)所定义的构造函数挥别附加上一些代码,以便将虚函数指针初始化,这些代码必须被附加在任何基类构造函数之后,任何使用者供应代码之前。

    2)合成一个拷贝构造函数和一个拷贝复制构造函数并且它不再是无用的,但是其隐式的虚构函数还是无用的。如果一个类对象被初始化或者以一个派生类对象赋值,那么以位为基础的操作可能对虚函数指针带来非法设定。

15、C++标准要求编译器尽量延迟必要成员函数(构造、拷贝)的实际合成操作,知道真正遇到其使用场合。

16、什么时候需要一个拷贝构造函数:当你的类有成员函数以传值的方式传回一个局部类对象。

17、继承体系的对象构造,当有一个构造函数被调用时,编译器会对构造函数进行扩充,扩充程度视继承体系确而定,一般而言编译器所做的扩充操作大约如下:

    1)成员初始化列表中的数据成员初始化操作会被放进构造函数本体,并以成员声明顺序为顺序。

    2)如果一个成员没有出现在成员初始化列表中,但是它有一个默认构造函数,这个默认构造函数必须被调用。

    3)在那之前,如果有虚函数机制,那么类对象的虚函数指针必须设定初值,指向虚函数表。

    4)所有上一层积累的构造函数必须被调用,以基类的声明顺序为顺序  :                                                                                                 

        *如果基类被列于成员初始化列表中,那么任何显式指定的参数都应该传递过去。

        *如果基类没有被列于成员初始化列表中,但是它有默认构造函数,则调用。

        *如果基类是多重继承下的第二或后继基类,那么this指针必须有所调整。

   5)所有的虚基类构造函数必须被调用,从左到右,从深到浅:

        *如果类被列于成员初始化列表中,那么有任何显式指定的参数都应该传递过去,如果没有列于初始化列表,而类有一个默认构造函数,调用。

        *此外,类中的每一个虚基类对象的偏移位置必须在执行期可被存取。

       *如果类对象是最底层的类,其构造函数可能被调用。

18、如果将一个类的析构函数定义为inline,则每一个调用操作都会在调用地点扩展开。

19、在声明一个拷贝构造函数和拷贝运算符时,一个新手最容易忘记检查自我指派的操作是否正确。在进行这两个函数的编写时,先判断传进来的对象是否等于this指针,如果相等,直接返回this指针指的值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值