C++ 析构和构造

1. 析构为构造的逆序,单继承派生类只有一个基类或虚基类,根据四个优先级别确定构造顺序;
  • 调用派生类虚基类的构造函数,无论列出总会被执行;
  • 调用派生类基类的构造函数,无论列出总会被执行;
  • 按照派生类实例数据成员声明的顺序,一次初始化实例数据成员或调用构造函数,对象无论是否列出总会被构造;
  • 最后执行派生类的构造函数;
2. 基类、对象成员不列出时自动调用无参构造函数;
3.以下情况派生类必须定义自己的构造函数:
  • 虚基类或基类只定义了带参数的构造函数;-
  • 派生类自定义了引用或只读成员(必须在冒号后列出以便初始化)而且不使用{}初始化全部都是公有成员的成员;
  • 派生类需要使用带参数的构造函数。
#include <iostream>

using namespace std;
class A
{
    int a = 0;

public:
    A() : a(8) { cout << a; }//非const实例数据成员a,可在函数体内再次对a赋值
    A(int x) : a(x) { cout << "construct A "<<a; }
    ~A() { cout << "Destruct A" << a << endl; }
};
class B : A
{ //私有继承,等价于class B: private A{
    int b, c;
    const int d;
    A x, y, z;

public:
    B(int v) : b(v), y(b + 2), x(b + 1), d(b), A(v)
    { //初始化与冒号后出现顺序无关
    /*
       
        初始化 A(v) x y z 分别输出 1 2 3 8
    */
        c = v;//b, c可再次赋值
        cout << b << c << d;
        cout << "C" << endl;
    }
    ~B() { cout << "Desturct B" << endl; }
};
int main()
{
    B z(1);
    return 0;
}
输出结果
construct A 1
construct A 2
construct A 3
8
111C
Desturct B
Destruct A 8
Destruct A 3
Destruct A 2
Destruct A 1
注意:

  • 基类的静态变量或全局变量
  • 派生类的静态变量或全局变量
  • 基类的成员变量
  • 派生类的成员变量

  • 成员变量在使用初始化列表初始化时,与构造函数中初始化成员列表的顺序无关,只与定义成员变量的顺序有关。
  • 如果不使用初始化列表初始化,在构造函数内初始化时,此时与成员变量在构造函数中的位置有关。
  • 类中const成员常量必须在构造函数初始化列表中初始化。
  • 类中static成员变量,必须在类外初始化。

4. 关于引用变量

  • 若有址引用变量r引用的是一个对象v,则对象的
    构造和析构由对象v完成,而不应该由有址引用
    变量r完成;
  • 若被r有址引用的对象由自动调用构造函数的new
    生成,则r必须用能自动调用析构函数的delete &r
    析构并释放对象内存,否则将产生内存泄漏;
  • 若被r指向的对象是用new生成的,则指针变量r必
    须用delete r析构并释放对象内存,不能使用不调
    用析构函数的free®,否则将产生内存泄漏;

示例代码
#include <iostream>

using namespace std;

class A
{
    int *s; //有私有实例数据成员,必须定义构造函数
public:
    A(int x)
    {
        s = new int[x];
    }
    ~A()
    {
        if (s)
        {
            delete s;
            s = 0; //相当于s=NULL
        }
    }
};
int main()
{
    A x(3),&r = x;//返回时自动析构x,r共享对象x不负责构造和析构
    A &p = *new A(5);//有值引用p被编译成指针,p代表对象 A(5)
    A *q = new A(9);//分配一块空间后,构造对象 即s分配一块空间
    delete &p;// &p 表示取p 引用的对象的地址
    delete q;//释放对象赵勇空间之前自动调用析构函数释放 s
    return 0;

}
发布了52 篇原创文章 · 获赞 15 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/jzj_c_love/article/details/102728090