copy构造函数的三种调用时机

什么是copy构造函数

首先对于普通类型的对象来说,它们之间的复制是很简单的。就类对象而言,相同类型的类对象是通过拷贝构造函数来完成整个复制过程的。

copy构造函数调用时机
1. 对象需要通过另外一个对象进行初始化


#include "iostream"
using namespace std;

class Test{
public:
    Test(int a=0,int b=0){
        m_a=a;
        m_b=b;
        cout<<"有参数构造函数"<<endl;
    }
    //赋值构造函数(copy构造函数)
    Test(const Test&obj){
        cout<<"copy构造函数"<<endl;
        m_a=obj.m_a+100;
        m_b=obj.m_b+100;
        cout<<"m_a="<<m_a<<endl;
        cout<<"m_b="<<m_b<<endl;
    }

    ~Test(){
        cout<<"析构函数"<<endl;
    }
protected:
private:
    int m_a;
    int m_b;
};
//1 copy构造函数 (用一个对象初始化另一个对象)
void main(){
    Test t1(1,2);//有参构造函数
    Test t0(3,4);//有参构造函数
    //Test t2=t1;
    Test t2(t1);//copy构造函数 
    system("pause");
}

2.对象以值传递的方式传入函数参数

#include "iostream"
using namespace std;

class Location
{
public:
    Location(int xx=0,int yy=0){
        X=xx;
        Y=yy;
        cout<<"有参构造函数"<<endl;
    }
    Location(const Location&obj){
        X=obj.X+1;
        Y=obj.Y+1;
        cout<<"copy构造函数"<<endl;
    }
    ~Location(){
        cout<<X <<" "<< Y <<"析构函数"<<endl;
    }
    int getX(){
        return X;
    }
    int getY(){
        return Y;
    }

private:
    int X;
    int Y;
};
void f(Location p){
    cout<<p.getX()<<endl;
}
void playobj(){
    Location a(1,2);
    Location b=a;//copy构造函数
    f(b);//实参初始化形参,会调用copy构造函数
}
void main(){
    playobj();
    system("pause");
}
调用f()时,会产生以下几个重要步骤:
(1).b对象传入形参时,会先会产生一个临时变量,就叫 c 吧。
(2).然后调用拷贝构造函数把b的值给c。 
(3).等f()执行完后, 析构掉c对象。

3. 对象以值传递的方式从函数返回

#include "iostream"
using namespace std;

class Location
{
public:
    Location(int xx=0,int yy=0){
        X=xx;
        Y=yy;
        cout<<"有参构造函数"<<endl;
    }
    Location(const Location&obj){
        X=obj.X+1;
        Y=obj.Y+1;
        cout<<"copy构造函数"<<endl;
    }
    ~Location(){
        cout<<X <<" "<< Y <<"析构函数"<<endl;
    }
    int getX(){
        return X;
    }
    int getY(){
        return Y;
    }

private:
    int X;
    int Y;
};
Location g(){
    Location A(1,2);
    return A;//copy构造函数
}
void playobj(){
    g();//g返回了一个匿名对象,A是局部变量,无法返回
}
void playobj2(){
    //用匿名对象初始化m,把匿名对象转成m(扶正)。不会被析构,playobj2结束时候析构
    Location m= g();//g返回了一个匿名对象,A是局部变量,无法返回
    cout<<"-------------"<<endl;
}
void playobj3(){
    Location m2(1,2);
    m2= g();
    cout<<"-------------"<<endl;
}
void main(){
    playobj3();
    system("pause");
}
当g()函数执行到return时,会产生以下几个重要步骤:
(1). 先会产生一个临时变量,就叫XXXX吧。
(2). 然后调用拷贝构造函数把A的值给XXXX。
(3). 在函数执行到最后先析构A局部变量。
(4). 等g()执行完后再析构掉XXXX对象。

这里写图片描述
此处析构两次哦。(A和XXXX)

注意:

    当调用playobj2()时候,A是局部变量,无法返回,g返回了一个匿名对象,用匿名对象初始化m,把匿名对象转成m(扶正)。不会被析构,playobj2结束时候析构。
    因此结果:

result

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值