复制构造函数学习

       今天和朋友讨论一个新手写的小程序,由于那个程序的问题太多了,并且自己的基础也不是很扎实,所以就变成了我两对问题的讨论,中间讨论的一个问题就是复制构造函数,讨论了半天,终于是扯清了,于是分享一下。

       首先说一下复制构造函数究竟是个什么东西,本质上说,复制构造函数也就是一种构造函数,只是他的使用情况不同,不需要程序员对其进行显式调用。

       在说一下复制构造函数的使用时间,主要由三种情况会使用:

          1.使用同一类型的类对象对另一个类对象进行初始化时;

          2.当一个对象以值的形式传递给一个函数时;

          3.当一个函数按值返回一个对象时。

       在一般情况下,我们并不知道复制构造函数的存在,因为当我们没有对复制构造进行申明时,系统会自动为我们分配一个默认复制构造函数,该函数的功能仅仅是对类中的成员进行简单的复制到另一个对象,如果在类中不使用指针变量时,这个函数不会出现什么问题,但当类中存在指针时,问题就出现了。

       当我们使用一个类的对象a对另一个类对象b进行初始化时,系统调用默认复制构造函数对其进行初始化,如是,系统就会将b中成员的指针赋值给a中指针成员,是a、b中的指针成员指向同一片内存,如是,当我们在某一时刻结束a或b的生命期(将其销毁delete)时,b或a中的指针指向了一个已经析构了的堆空间,当我们在使用这个指针时,由于他已经不存在了,系统就会崩溃。

       上面所说的就是“浅复制”,可以看出,系统提供的复制构造函数在此时已经不能满足我们的要求了,我们需要自己设计自己的复制构造函数,使上面a、b对象成员指向的内存空间分离,这样我们在其中的一个对象生命期结束时,仍能保证另一个对象可以正常使用。

       如何去设计这个复制构造函数呢?思路很简单,就是当我们进入复制构造函数进行成员变量复制时,我们不使用复制地址的方式,我们为新的成员变量开辟一块新的内存空间,然后将原成员变量的值写到这块内存空间中,这样就完成了分离工作,这也就是我们所谈到的“深层复制”。下面是一个例子:

#include <iostream>
using namespace std;
class CA
{
public:
	CA(int b,char* cstr)
	{
		a=b;
                  str=new char[b];
		strcpy(str,cstr);

	}
	CA(const CA& C)
	{
	         a=C.a;
		str=new char[a]; //深度复制   新开辟一块堆控件来进行复制

		if(str!=0)
		    strcpy(str,C.str);  //仅仅对成员变量的值进行复制,保证复制之后两个对象之间指向不同堆空间
	}
	void Show()
	{
		cout<<str<<endl;
	}
	~CA()
	{
		delete str;
	}
private:
	int a;
	char *str;
};
int main()
{
	CA A(10,"Hello!");
	CA B=A;
	B.Show();
	return 0;
}

      也许,有比较细心的朋友会看到,我在构造函数CA(int b,char* cstr)中开辟了一块str的堆空间,又在复制构造函数CA(const CA& C)中开辟了一块str的堆空间,但只析构一次,会不会造成内存泄露?嘿嘿,担心多余了,我刚开始就说过了,复制构造函数也是构造函数,因此他们中间只有一个会执行,不会同时开辟两块空间。

    下面说一下复制构造函数使用的时间,前面已经说了有三种情况,现在就不再说了,主要是对其进行一下实例分析吧。

#include "iostream"
using namespace std;
class CA
{
public:
CA(){ cout<< "construct be called." << endl;}
CA(CA& ra){ cout << "copy construct be called. "<< endl;}
};
CA fun(CA a)
{
CA na(a);
return na;
}

int main(int argc, char* argv[])
{
CA fa;
CA fb = fun(fa);
return 0;
}


      先说一下结果吧,复制构造函数会执行四次!到底是那四次呢?

       1、调用fun(fa)时,即情况2,我们知道fun函数申明为CA fun(CA a),对象按值传递,那么系统会调用复制构造函数创建一个临时对象a

       2、调用CA na(a)时,即情况1

       3、调用return na时,即情况3

       4、调用CA fb = fun(fa)是,即情况1,使用fun函数的返回值对fb进行初始化

 

好了,水平有限,就写这样了,欢迎拍砖

注:文中代码均摘自网络,因为看到这些例子都很好的,不需要自己再编写了,呵呵

 

 

 

 


 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值