类-构造与析构执行顺序详解

 1.示例说明
  以下面的程序说明函数的执行顺序:
  1)定义String类,构造和析构会打印其中的字符串
  2)定义一个基类Base,类中含有两个String
  3)从基类Base派生出Derive类,类中含有一个String
  每个类函数成员都会将执行函数名打印出来。
struct String{
	String(const string& s = ""):str(s) 
		{cout<< "String():"<< str << endl;}
		
	String(const String& s):str(s.str) 
		{cout<< "String(const String& s):"<< str << endl;}
			
	String(String&& s):str(std::move(s.str)) 
		{cout<< "String(String&& s):"<< str << endl;}
		
	String& operator=(const String& s)
		{str = s.str;  cout<< "String& operator=(const String& s)"<< str << endl;}
	
	String& operator=(String&& s)
		{str = std::move(s.str); cout<< "String& operator=(String&& s)"<< str << endl;}
	
	~String() 	{cout<< "~String():" << str << endl;}
		
	string str;
};

//基类 
struct Base{
	Base(const String& _a, const String& _b):b(_b), a(_a) 
		{cout<<"Base()"<<endl;}
		
	virtual ~Base() {cout<<"~Base()"<<endl;}
	
private:
	String a; 	 
	String b;
};

//派生类 
struct Derive:public Base{
	Derive(const String& _a, const String& _b, const String& _c):
		Base(_a,_b), c(_c)	{cout<<"Derive()"<<endl;}
		
	virtual ~Derive() {cout<<"~Derive()"<<endl;}
private:
	String c;
};

 情形一:
 函数中,先构造的变量后析构,函数中若存在作用域,作用域离开后在作用域中创建的变量会进行析构
int main(int argc, char** argv) {
	String A("First");
	{
		String tmp("tmp");
	}
	String B("Second");
	return 0;
}


//定义结果
String():First
String():tmp
~String():tmp
String():Second
~String():Second
~String():First

--------------------------------
Process exited after 0.09922 seconds with return value 0
情形二:
数组中,构造从底到高,析构从高到低
//数组中打印
int main(int argc, char** argv) {
	String array[] = {string("first"), string("second")}
	return 0;
}

//打印结果
String():first
String():second
~String():second
~String():first

--------------------------------
Process exited after 0.1071 seconds with return value 0
情形三:
容器中,构造和析构顺序与具体容器实现有关系。
int main(int argc, char** argv) {
	//创建的两个临时变量在vec构造函数执行完成后,销毁
	vector<String> vec = {String("first"), String("second")};
	
	cout<< "\nprint vec:";
	for(auto &s :vec)
		cout<< s.str << " ";
	cout<<endl<<endl;
	
	//vector容器从头到尾进行析构
	return 0;
}

//打印结果
String():first				//构造函数创建两个变量,构造完成后自动销毁
String():second
String(const String& s):first
String(const String& s):second
~String():second
~String():first

print vec:first second

~String():first
~String():second

--------------------------------
Process exited after 0.1046 seconds with return value 0
情形四:
表达式中函数的调用顺序与编译相关,并非一定从左到右地依次调用;
int main(int argc, char** argv) {
	//由于属于临时对象,输出完成后变直接调用析构函数 
	cout<< String("first").str << "  " <<String("Second").str << endl;
	cout<< "\n测试结束" <<endl; 
	return 0;
}

//打印结果
String():Second
String():first
first  Second
~String():first
~String():Second

测试结束

--------------------------------
Process exited after 0.1141 seconds with return value 0
情形五:
类构造执行,成员按定义顺序构造后再执行构造函数体,析构时,先执行析构函数体,再逆序销毁成员;
注意:构造函数初始值顺序不能改变类中成员定义顺序,此外,函数参数的构造顺序与编译器相关,示例中
构造顺序从右到左
int main(int argc, char** argv) {
	Base base(String("first"), String("Second"));
	
	cout<< "测试结束" <<endl; 
	return 0;
}

//打印结果
String():Second
String():first
String(const String& s):first
String(const String& s):Second
Base()
~String():first
~String():Second
测试结束
~Base()
~String():Second
~String():first

--------------------------------
Process exited after 0.1325 seconds with return value 0


情形六:
派生类的构造:基类先构造,而析构则从派生类开始先析构
//打印结果
String():third
String():Second
String():first
String(const String& s):first
String(const String& s):Second
Base()
String(const String& s):third
Derive()
~String():first
~String():Second
~String():third

测试结束
~Derive()
~String():third
~Base()
~String():Second
~String():first

--------------------------------
Process exited after 0.1188 seconds with return value 0






  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值