【题目】C++拷贝构造函数与C++临时对象

一、拷贝构造函数

       1、拷贝构造函数定义

                    

class A { private: int _a;

public: A(){}; A(const A&); //定义拷贝构造函数,一定要有一个实现 };

A::A(const A& Aa) {  cout<<"拷贝构造"<<endl; }

     2、调用拷贝构造函数的时机 

//E1、声明语句中,一个对象初始化另一个对象,前提是类必须存在拷贝构造函数
A obj1;
A obj2 = obj1;
//E2、对象作为参数
void get(A obj) {}             //调用这个函数的时候,先会调用拷贝构造函数
//E3、函数返回一个对象
A get(){ A obj ; return obj;}  //

二、C++浅拷贝和深拷贝【7】

       1、浅拷贝

class A
{
private:
	int _a;
public:
	A(){};
	A(const A&);
	void setData(int a1){	_a = a1;  }
	void Output(){	cout<<"A::a = "<<_a<<endl;  }
};
A::A(const A& Aa)              //如果是浅拷贝,则,在这里直接将一个对象的值赋值给另外一个对象
{
	 _a = Aa._a;
	cout<<"拷贝构造"<<endl;
}
int main(int argc, char* argv[]) 
{
	A a;
	a.setData(10);
	A b = a;
	b.Output();
}

       2、深拷贝           

CExample::CExample(const CExample& RightSides)
{
     pBuffer=NULL;
     *this=RightSides     //调用重载后的"="
}
//赋值操作符重载
CExample & CExample::operator = (const CExample& RightSides)
{
     nSize=RightSides.nSize; //复制常规成员
    char *temp=new char[nSize]; //复制指针指向的内容 
     memcpy(temp,RightSides.pBuffer,nSize*sizeof(char));
    delete []pBuffer; //删除原指针指向内容   (将删除操作放在后面,避免X=X特殊情况下,内容的丢失)
     pBuffer=temp;   //建立新指向
    return *this
}

【点评】深拷贝,会将对象指针指向的动态内存中的值,拷贝到另外一个对象中,以防止内存泄露。另外,拷贝是将一个有值的对象赋值给空值的对象,而"赋值"操作符是将原来有值的对象中的值覆盖,调用的是"=重载函数"。

三、拷贝构造函数调用时机

        1、对象作为参数,调用构造函数

//浅拷贝中的例子加入如下代码
bool SetA(A a)
{	
     return true;
}
//void main()
 SetA(a);
//汇编代码
53:       A b = a;
004012CA   lea         eax,[ebp-4]    //a的指针
004012CD   push        eax
004012CE   lea         ecx,[ebp-8]    //b的指针
004012D1   call        @ILT+60(A::A) (00401041)
54:       b.Output();
004012D6   lea         ecx,[ebp-8]
004012D9   call        @ILT+15(A::Output) (00401014)
55:       SetA(a);
004012DE   push        ecx     
004012DF   mov         ecx,esp                    //当前栈已经开辟了临时对象空间,相当于b的指针
004012E1   lea         edx,[ebp-4]
004012E4   push        edx            //a的指针
004012E5   call        @ILT+60(A::A) (00401041)
004012EA   call        @ILT+10(SetA) (0040100f)   //已经拷贝了到了ecx,所以就直接调用SetA(),此时esp就是临时对象的指针
004012EF   add         esp,4                      //esp+4 还是指向临时对象
2、返回一个对象             
CExample GetExpFun()
{
       return g_objExp;
}
    objExp2 = GetExpFunc();                
004013E4   lea         ecx,[ebp-40h]           //返回的临时对象空间是进入main函数的时候,提前分配好的。
004013E7   push        ecx                     //先将对象压栈       
004013E8   call        @ILT+25(GetExpFun)      //调用函数

 【点评】 返回对象时,也是在当前栈分配了临时空间,会调用在函数中,调用拷贝构造函数,来赋值给临时空间。相当于一个中转战,先拷贝构造函数赋值给临时空间,再用它。

参考:1、C++拷贝构造函数(深拷贝、浅拷贝)

2、C++拷贝构造函数和赋值操作

3、02类与对象(5)-拷贝构造

4、拷贝构造函数

5、C++临时对象的学习笔记

6、拷贝构造函数的调用

7、拷贝构造函数与赋值运算符重载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值