复合类的构造函数

复合类的初始化
直接贴代码:

#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。这条语句结束之后,拷贝好的对象马上就被析构,之后的输出就是根据构造的顺序,反向析构。

总结:我们在构造符合类的构造函数的时候如果想要防止产生多个对象,可以使用初始化列表的方式进行构造。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值