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