复合类的初始化
直接贴代码:
#include <iostream>
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
class A
{ private:
int x;
public:
A():x(0){cout<<x<<",A0 constructor"<<endl;}
A(int x1):x(x1){cout<<x<<",A1 constructor"<<endl;}
A(A& a){x=a.x+1;cout<<x<<",A copy constructor"<<endl;}
~A(){cout<<x<<",A destructor"<<endl;}
int print(){
return x;
}
};
class B
{ private:
string name;
A a1;
public:
B():name("Java"){cout<<"B0 constructor"<<endl;}
// B(A a,string s):name(s),a1(a){cout<<"B1 constructor"<<endl;}
B(A a,string s){
name=s;
A a1(a);
cout<<"B1 constructor"<<endl;
}
B(string s,int x):name(s),a1(x){cout<<"B2 constructor"<<endl;}
A print(){
return a1;
}
~B(){cout<<"B destructor"<<endl;}
};
int main()
{
B b1;
// A a(10);B b2(a,"c++");
// cout<<b2.print().print()<<endl;
// B b3("c",20);
return 0;
}
结果:
分析:
第一种情况B调用不含参数的构造函数,
在给成员函数赋值的时候,成员私有类发现没有给自己初始化列表,就会A自己自动调用无参构造函数初始化。之后B再构造完成。
int main()
{
// B b1;
// A a(10);B b2(a,"c++");
// cout<<b2.print().print()<<endl;
B b3("c",20);
return 0;
}
结果:
分析:
第二种情况,
我们根据代码可以知道我们B的构造函数中使用了初始化列表,因此A类先构造,然后B再完成构造。
int main()
{
// B b1;
A a(10);B b2(a,"c++");
cout<<b2.print().print()<<endl;
// B b3("c",20);
return 0;
}
结果:
分析:
第三钟情况,
我们尝试不适用初始化列表进行构造,以上是得到的结果,我们根据这个结果进行分析,首先我们a先构造,第二行是我们调用B的构造函数的时候,A进行了拷贝,进入到我们的函数体的时候,因为没有初始化列表对数据成员私有类构造,a1自己率先调用了无参构造函数,第三行输出,第四行是对函数体里面的a1进行局部拷贝,之后B完成拷贝,函数体结束后,局部变量a1率先被析构,私有对象没有发生改变,然后就是形参被析构。
下一行,返回的x值为什么是1呢?因为在返回一个A对象的时候对a1进行了拷贝,所以x的值变成了1。这条语句结束之后,拷贝好的对象马上就被析构,之后的输出就是根据构造的顺序,反向析构。
总结:我们在构造符合类的构造函数的时候如果想要防止产生多个对象,可以使用初始化列表的方式进行构造。