构造、析构、拷贝(Semantics of Construction,Destruction,and Copy)

1、继承体系下的对象构造

当我定义一个object如下

T object;

如果T有一个默认构造函数,它会被调用。
比较不明显的是构造函数内部有大量的隐藏代码,因为编译器会扩充构造函数,一般而言编译器所做的扩充如下:

  • 记录在成员初始化列表中的数据成员初始化操作会被放到构造函数体中,并以成员的声明顺序为顺序。
  • 如果成员没有在初始化列表中,但是它有一个默认构造函数,那么它的默认构造函数也要被调用
  • 如果有虚函数,须在构造函数里设置虚指针。
  • 如果有基类并且基类有构造函数,基类的构造函数必须被调用,以声明顺序为顺序,和初始列表的顺序无关。
  • 虚基类的构造函数也必须被调用,顺序由左向右
2、虚指针(vptr)初始化

如果在构造函数里调用虚函数,那么调用的将是当前类里的那个函数,不会调用派生类里的虚函数。

原因是:vptr的设置时间点是在 所有基类构造完之后,用户代码之前。

下面是类A、B、C的代码:

#include<iostream>

class A
{
public:
    A() { std::cout << "A:" << size() << std::endl; }
    virtual int size() { return sizeof(A); }
};
class B : public A
{
public:
    B() { std::cout << "B:" << size() << std::endl; }
    virtual int size() { return sizeof(B); }
    int b;
};
class C : public B
{
public:
    C() { std::cout << "C:" << size() << std::endl; }
    virtual int size() { return sizeof(C); }
    int c;
};

int main()                           
{
    A* p = new C;
    delete p;
    return 0;
}

执行结果:

A:4
B:8
C:12

2.1、构造函数的执行顺序
  1. 在派生类中,所有基类构造会被调用。
  2. 上述完成后,初始化vptr。
  3. 如果有初始化列表的话,将初始化列表扩展到构造函数中。
  4. 最后执行程序员提供的代码
3、对象复制

一个类的拷贝复制操作,在以下情况下不会表现出按位拷贝的语意:

  1. 当类中有一个成员,而其有一个拷贝赋值函数时。
  2. 当类有一个基类,而其有一个拷贝赋值函数时。
  3. 当类中声明了一个虚函数时。
  4. 当类有虚基类时,
4、析构

如果类没有定义析构函数,那么只有在类内的成员或基类拥有析构函数时,编译器才会合成一个析构出来。

4.1、析构函数的执行循序
  1. 析构函数本体的代码
  2. 如果成员对象有析构函数,那么他们会以与声明顺序相反的循序执行。
  3. 如果对象内有虚函数,那么重新设之vptr,指向适当的基类的虚表
  4. 如果有任何的非虚基类拥有析构函数,那么以声明顺序相反的顺序执行。
  5. 如果有任何虚基类拥有析构函数,那么他会以构造顺序相反的循序执行

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-14 05:16:05       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-14 05:16:05       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-14 05:16:05       57 阅读
  4. Python语言-面向对象

    2024-07-14 05:16:05       68 阅读

热门阅读

  1. 天童教育:要增强孩子的自理能力

    2024-07-14 05:16:05       24 阅读
  2. 测试工程师面试热门问题(六)

    2024-07-14 05:16:05       19 阅读
  3. JVM:自动垃圾回收

    2024-07-14 05:16:05       23 阅读
  4. 使用openssl生成自签名证书

    2024-07-14 05:16:05       26 阅读
  5. 【TS】如何使用联合类型和交叉类型

    2024-07-14 05:16:05       26 阅读
  6. C语言——printf、scanf、其他输入输出函数

    2024-07-14 05:16:05       26 阅读
  7. C语言实现数据结构B树

    2024-07-14 05:16:05       26 阅读
  8. 前端热门面试题二

    2024-07-14 05:16:05       25 阅读
  9. 使用 git 和 GitHub 互动

    2024-07-14 05:16:05       21 阅读
  10. MySQL入门学习-深入索引.匹配顺序

    2024-07-14 05:16:05       23 阅读