c++中不同场景构造函数的次序问题:

本文详细解析了不同类型的构造函数和析构函数的工作原理,包括普通类、继承与派生类、虚基类以及虚函数的构造过程。通过具体代码示例展示了构造与析构的顺序,有助于理解C++中对象的创建与销毁机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.普通类的构造函数:
(1)首在定义类时传参数指针this到构造函数
(2)按类中数据成员声明的次序一一进行分配内存空间并初始化
(3)执行构造函数的函数体
  普通类的析构函数:
(1)首先执行函数体
(2)对成员变量释放空间
2.继承与派生的构造函数
(1)首在定义类时传参数指针this到构造函数
(2)依照基类在构造函数中的定义次序调用基类的构造函数,初始化他们的成员(从左到右)
(3)按类中数据成员声明的次序一一进行分配内存空间并初始化
(4)执行构造函数的函数体
  继承与派生的构造函数:Derived::Derived(const Derived&v):Base(v){}
(1)执行次序与构造函数相同
  继承与派生的析构函数:次序与虚构函数相反
例子:
#include<iostream>
using namespace std;
class A
{
public:
	A(){ cout<<"A"<<endl;}
	~A(){cout<<"~A"<<endl;}
};
class B:public A
{
	A *p;
public:
	B(){ cout<<"B";p=new A();}
	~B(){ cout<<"~B";delete p;}
};
int main()
{
	B obj;
	return 0;
}
输出:ABA~B~A~A


3.虚基类的构造函数
(1)如果该派生类有直接或间接的虚基类。则先执行虚基类的构造函数
(2)如果有其他基类,则按照他们在继承中声明列表中出现的次序。分别执行他们的构造函数,但是构造过程中不执行他们的虚基类的构造函数
(3)对派生类中新增成员进行初始化
(4)执行构造函数函数体
例子:
#include <iostream> 
using namespace std;
class A 
{ 
	int x; 
public: 
	A(int a){x=a;} 
	void Display() { cout<<x<<endl; } 
}; 
class B:virtual public A 
{ 
	int y; 
public: 
	B(int a,int b):A(a) { y=b; }
 
	void Display() { cout<<y<<endl; } 
}; 
class C:virtual public A 
{ 
	int z; 
public: 
	C(int a,int b):A(a) { z=b; } 
	void Display() { cout<<z<<endl; } 
}; 
class D:public B,public C 
{ 
	int m,n; 
public: 
	D(int a,int b,int c,int d):B(c,a),C(c,b),A(c) { m=d; n=a; } 
	void Display() 
	{ 
		A::Display(); 14
		B::Display(); 12
		C::Display(); 13
		cout<<m<<","<<n<<endl;
	} 
}; 
void main() 
{ 
	D dd(12,13,14,15); 
	dd.Display(); 	
}
输出:14 12 13 15 12



4.虚函数
(1)定义虚基类的成员函数为虚函数
(2)定义派生类同名函数同参数同返回值
(3)定义一个基类指针指向派生类
(4)通过使用指针动态绑定派生类的成员函数
例子:
#include<iostream>
using namespace std;
class Base
{
public:
	Base() {  Show(); }
	virtual void Show() { cout << "Base::Show" << endl; } 
	void Print() {   Show();  }
	virtual  ~Base()  { Show(); }
};
class Derived :public Base
{
public:
	Derived () {  Show(); }
	virtual void Show() { cout << "Derived::Show" << endl; }
	void Print() {	Show(); }
	virtual  ~Derived() {  Show(); }
};
void main()
{
	Base  b;
	Base* p = &b;
	p->Print();


	Derived d;
	p = &d;
	p->Print();
}
输出:
Base::Show
Base::Show
Base::Show
Derived::Show
Derived::Show
Derived::Show
Base::Show
Base::Show



结论
在类被构造的时候,先执行虚拟继承的父类的构造函数,然后从左到右执行普通继承的父类的构造函数,
然后按照定义的顺序执行数据成员的初始化,最后是自身的构造函数的调用。析构函数与之完全相反,互成镜像。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值