C++【07】复制构造函数

复制构造函数

  • 有一个参数,即对同类对象的引用
  • 形如 X::X(X& )或X::X(const X& ),二者选一,后者能以常量对象作为参数
  • 如果没有定义复制构造函数,那么编译器生成默认复制构造函数。默认的复制构造函数完成复制功能。

注意:复制构造函数与无参构造函数是不一样的!!无参构造函数不一定存在,复制构造函数一定存在。

class Cpmplex
{
    private:
        double real,imag;
};

Complex c1;//调用缺省无参构造函数
Cpmplex c2(c1);//调用缺省的复制构造函数,将c2初始化和c1一样。

如果自己定义了复制构造函数,则默认的复制构造函数不存在。

class Complex
{
    public:
        double real,imag;
    Complex(){}
    Complex(const Complex& c)
    {
        real=c.real;
        imag=c.imag;
        cout<<"Copy Constructor called";
    }

};

Complex c1;
Complex c2(c1);//调用自定义的复制构造函数,输出Copy Constructor called

复制构造函数起作用的三种情况

(1)当用一个对象去初始化同类的另一个对象时。

Complex c2(c1);
Complex c2=c1;//初始化语句,与以上语句等价。非赋值语句

(2)如果某函数有一个参数是类A的对象,那么改函数被调用时,类A的复制构造函数将被调用。

class A
{
    public:
        A(){};
        A(A& a)
        {
        cout<<"Copy constructor called"<<endl;
         }
};

void Func(A a1){}

int main()
{
    A a2;//创建对象,调用无参构造函数
    Func(a2);//调用类A对象的复制构造函数,输出Copy constructor called
//以上自定义类A的复制构造函数,并没有对进行一个复制操作。
//所以在Func(a2)时,形参不一定是实参的拷贝
    return 0;
}

(3)如果函数的返回值是类A的对象时,则函数返回时,A的复制构造函数被调用。

class A
{
    public:
        int v;
        A(int n){v=n;};
        A(const A& a){
            v=a.v;
            cout<<"Copy constructor called";
        }

};

A Func()
{
    A b(4);//将对象b的全局变量v初始化为4
    return b;//将对象b作为返回值时,调用对象b所属的类的复制构造函数,该函数被调用时输出Copy constructor called
}

int main()
{
    cout<<Func().v<<endl;//输出Copy constructor called
                         //输出 4
    return 0;
}

注意:对象间的赋值并不导致复制构造函数被调用

class CMyclass
{
    public:
        int n;
        CMyclass(){};
        CMyclass(CMyclass & c){n=2*c.n;}    

};

int main()
{
    CMyclass c1,c2;
    c1.n=9;
    c2=c1;//对象间的赋值,不调用复制构造函数
    CMyclass c3(c1);//调用复制构造函数
    CMyclass c4=c1;//用c1初始化c4,调用复制构造函数
    cout<<"c2.n="<<c2.n<<",";//输出c2.n=9,
    cout<<"c3.n="<<c3.n<<endl;//输出c3.n=18
    return 0;
}

常量引用参数的使用

void fun(CMyclass obj_)

{

cout<<"fun"<<endl;

}

(1)这样的函数,调用时生成形参会引发复制构造函数的调用,开销较大

(2)可以考虑使用CMyclass& 引用类型作为参数

(3)如果希望确保实参的值在函数中不应被改变,那么可以加const关键字

void fun(CMyclass & obj)
{
//将对象的引用作为形参,形参的变化同时使实参变化,需谨慎修改形参的值!!
}

//为了保证实参不被修改,在形参前加const关键字,就能够确保形参的改变不修改实参
void fun(const CMyclass & obj)
{

//函数中任何试图改变obj值的语句都将变成非法!!
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值