拷贝构造函数

1、定义

拷贝构造函数是一种特殊的构造函数,函数的名称和类名称相同,拷贝构造函数的参数必须有一个是本类型的一个引用。

2、用的场景

(1)类的对象以值传递的方式传入函数的参数;

例子

class A{
	public:
		A(int a){
			cout << "构造函数执行" << endl;
		}
		A(A &temp){
			c = temp.c;
			cout << "拷贝构造函数执行" << endl; 
		}
		
		~A(){
			cout << "析构函数执行"<<endl;
		}
		private:
			int c;
};

void fun(A temp)
{
	cout << "fun函数已经执行" <<endl;
}

int main()
{
	A test(2);
	fun(test);
	
	return 0;
}

上例子中当调用fun()函数的时候就会调用拷贝构造函数。

第一步先把test传给形参temp(传值时会临时生成一个A类型的temp) ,这时调用了构造函数

第二部当fun函数执行完时,调用析构 函数,析构C;

(2)类对象以函数返回值的形式进行返回(该种方法我用devC++编写的时候没有执行该构造函数,VS2013可以)

(3)类的对象需要用另一个类的函数进行初始化;

A c(3);
A b = c;
2、浅拷贝和深拷贝的理解

(1)默认构造函数

当个人没有显示得定义拷贝构造函数的时候,当出现上述用到拷贝构造函数的时候,编译器会自动的产生一个拷贝构造函数,但是这个构造函数完成的功能有限,只是通过“老”对象的数据成员的值对“新”成员进行赋值操作。

(2)浅拷贝

浅拷贝就是对象在复制的时候,支队对象中的数据成员进行简单的赋值,默认构造函数就是浅拷贝。一般浅拷贝就已经够用了,但是对象存在一些动态的成员的时候浅拷贝就不行了。下例就是浅拷贝不行的时候。

class Rect
{
public:
    Rect()      // 构造函数,p指向堆中分配的一空间
    {
        p = new int(100);
    }
    ~Rect()     // 析构函数,释放动态分配的空间
    {
        if(p != NULL)
        {
            delete p;
        }
    }
private:
    int width;
    int height;
    int *p;     // 一指针成员
};

int main()
{
    Rect rect1;
    Rect rect2(rect1);   // 复制对象
    return 0;
}

在这段代码运行结束之前,会出现一个运行错误。原因就在于在进行对象复制时,对于动态分 配的内容没有进行正确的操作。我们来分析一下:

    在运行定义rect1对象后,由于在构造函数中有一个动态分配的语句,因此执行后的内存情况大致如下:

 

 

    在使用rect1复制rect2时,由于执行的是浅拷贝,只是将成员的值进行赋值,这时rect1.p = rect2.p,也即这两个指针指向了堆里的同一个空间,如下图所示:

 

当然,这不是我们所期望的结果,在销毁对象时,两个对象的析构函数将对同一个内存空间释放两,这就是错误出现的原因。我们需要的不是两个p有相同的值,而是两个p指向的空间有相同的值,解决办法就是使用“深拷贝”。


(3)深拷贝

在“深拷贝”的情况下,对于对象中动态成员,就不能仅仅简单地赋值了,而应该重新动态分配空间,如上面的例子就应该按照如下的方式进行处理

class Rect
{
public:
    Rect()      // 构造函数,p指向堆中分配的一空间
    {
        p = new int(100);
    }
    Rect(const Rect& r)
    {
        width = r.width;
        height = r.height;
        p = new int;    // 为新对象重新动态分配空间
        *p = *(r.p);
    }
    ~Rect()     // 析构函数,释放动态分配的空间
    {
        if(p != NULL)
        {
            delete p;
        }
    }
private:
    int width;
    int height;
    int *p;     // 一指针成员
};

此时,在完成对象的复制后,内存的一个大致情况如下:

 

此时rect1的p和rect2的p各自指向一段内存空间,但它们指向的空间具有相同的内容,这就是所谓的“深拷贝”。

(注释:浅、深拷贝摘自http://www.baidu.com/link?url=tOZti-L4j-cCNlEWYHoOyKJqANdXP6obJY9RWafaZ4QHXzeq8hLSRUSWzoGz4cwIlY4JbtFkl9nDVGZJEvmh0_&wd=&eqid=92f6a11a001c0b8500000003572d9a6a)

注意:一个类中可以有多个拷贝构造函数。根据参数的不同区调用不同的构造函数。



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值