跳至主要內容

派生类的构造和销毁过程

张威大约 5 分钟c/c++继承

派生类的构造和销毁过程

  1. 构造函数和析构函数是不能继承的,为了对数据成员进行初始化,派生类必须
  2. 由于派生类对象通过继承而包含了基类数据成员,因此,创建派生类对象时,系统首先通过派生类的构造函数来调用
  3. 后对

形式

派生类名(总参数表): 基类构造函数(参数表)
{
    //函数体
};

如何初始化基类的成员变量

答:通过调用基类相应的构造函数

class Base
{
public:
	Base(int data) :ma(data)
	{
		cout << "Base()" << endl;
	}
	~Base()
	{
		cout << "~Base()" << endl;
	}
protected:
	int ma;
};

class Derive : public Base
{
public:
	Derive(int data):ma(data), mb(data)
	{
		cout << "Derive()" << endl;
	}
	~Derive()
	{
		cout << "~Derive() " << endl;
	}
private:
	int mb;
};

int main()
{
	Derive d(20);

	return 0;
}

程序出错:不允许我们派生类这样对从基类继承的ma进行初始化。在初始化列表中使用基类的构造来初始化ma

class Derive : public Base
{
public:
	Derive(int data):Base(data), mb(data)
	{
		cout << "Derive()" << endl;
	}
	~Derive()
	{
		cout << "~Derive() " << endl;
	}
private:
	int mb;
};
  • 派生类的构造函数和析构函数,负责初始化和清理派生类部分
  • 派生类从基类继承来的成员的初始化和清理由基类的构造函数和析构函数负责

派生类构造调用基类构造

派生类有显式定义构造函数,而基类没有显示定义构造函数

如果派生类有显式定义构造函数,而基类没有显示定义构造函数,则创建派生类的对象时,派生类相应的构造函数会被自动调用,此时都自动调用了基类缺省的无参构造函数

class Base 
{
pulbic:
    Base()
    {   
        cout << "Base()" << endl;   
    }
};
class Derived
: public Base 
{
public:
    Derived(long derived)
    : _derived(derived)
    {   
        cout << "Derived(long)" << endl;    
    }
    long _derived;
};
void test() 
{
    Derived d(1);
}

如果派生类没有显式定义构造函数,而基类有显示定义构造函数

如果派生类没有显式定义构造函数而基类有显示定义构造函数,则****。

class Base 
{
pulbic:
    Base(long base)
    {   
        cout << "Base(long)" << endl;
    }
private:
    long _base;
};
class Derived
: public Base 
{
public:
    //没有显示定义那就是编译器合成
};
void test()
{
    Derived d;//error
}

派生类有构造函数,基类有默认构造函数

如果派生类有构造函数,基类有默认构造函数,则创建派生类的对象时,基类的默认构造函数会自动调用,如果你想调用基类的有参构造函数,必须要在派生类构造函数的初始化列表中显示调用基类的有参构造函数

派生类和基类都有构造函数,但基类没有默认的无参构造函数

如果派生类和基类都有构造函数,但基类没有默认的无参构造函数,即基类的构造函数均带有参数,则派生类的每一个构造函数必须在其初始化列表中显示的去调用基类的某个带参的构造函数。 如果派生类的初始化列表中没有显示调用则会出错,因为基类中没有默认的构造函数。

class Base
{
pulbic:
    Base(long base) 
    {   
        cout << "Base(long)" << endl;   
    }
private:
    long _base;
};
class Derived
: public Base 
{
public:
    Derived(long base, long derived)
    : Base(base)
    , _derived(derived)
    {   
        cout << "Derived(long, long)" << endl;
    }
    long _derived;
};
void test()
{
    Derived d(1, 2);
}

必须将基类构造函数放在派生类构造函数的,以调用基类构造函数完成基类数据成员的初始化

[必须在初始化列表中进行初始化的情况有哪些](https://iszhwei.gitee.io/ccpp/03 类和对象/构造函数和析构函数.html#必须在初始化列表中进行初始化的情况有哪些)

派生类构造函数调用顺序

  1. 完成对象所占整块内存的开辟,由系统在调用构造函数时自动完成
  2. 调用基类的构造函数完成基类成员的初始化
  3. 若派生类中含**,则必须在初始化表中完成其初始化**。
  4. 派生类构造函数体执行

派生类对象的销毁

当派生类对象被删除时,派生类的析构函数被执行。析构函数同样不能继承,因此,在执行派生类析构函数时,基类析构函数会被。执行顺序是先执行派生类的析构函数,再执行基类的析构函数,和执行构造函数时的顺序正好。当考虑对象成员时,继承机制下析构函数的调用顺序:

  1. ,释放派生类成员可能占用的外部资源(堆内存 文件)
  2. 再调用派生类中****
  3. 最后调用****,释放派生类内存中从基类继承来的成员可能占用的外部资源