编程日记:c++ 类的拷贝构造

调用拷贝构造函数的情形

  在C++中,下面三种对象需要调用拷贝构造函数(有时也称复制构造函数):

1) 一个对象作为函数参数,以值传递的方式传入函数体;

2) 一个对象作为函数返回值,以值传递的方式从函数返回;

3) 一个对象用于给另外一个对象进行初始化(常称为复制初始化);

 

原则:对于凡是包含动态分配成员或包含指针成员的类都应该提供拷贝构造函数;

在提供拷贝构造函数的同时,还应该考虑重载"="赋值操作符号

 

拷贝构造函数必须以引用的形式传递(参数为引用值)

 

复制初始化例子

以下讨论中将用到的例子:

class CExample

{

public:

CExample(){pBuffer=NULL;nSize=0;}

~CExample(){delete[]pBuffer;}

void Init(int n){pBuffer=new char[n]; nSize=n;}

private:

char *pBuffer; //类的对象中包含指针,指向动态分配的内存资源

int nSize;

};

  这个类的主要特点是包含指向其他资源的指针,pBuffer指向堆中动态分配的一段内存空间。

int main(int argc, char*argv[])

{

CExample theObjone;

theObjone.Init(40);

//现在需要另一个对象,并将它初始化为theObjone

CExampletheObjtwo=theObjone;

...

}

  语句"CExampletheObjtwo=theObjone;"theObjone初始化theObjtwo

  回顾一下此语句的具体过程:首先建立对象theObjtwo,并调用其构造函数,然后成员被复制初始化。

其完成方式是内存拷贝,复制所有成员的值。完成后,theObjtwo.pBuffer==theObjone.pBuffer

即它们将指向同样的地方,指针虽然复制了,但所指向的空间并没有复制,而是由两个对象共用了。这样不符合要求,对象之间不独立了,并为空间的删除带来隐患。所以需要采用必要的手段来避免此类情况:可以在构造函数中添加操作来解决指针成员的这种问题。

  所以C++语法中除了提供缺省形式的构造函数外,还规范了另一种特殊的构造函数:拷贝构造函数,一种特殊的构造函数重载。上面的语句中,如果类中定义了拷贝构造函数,在对象复制初始化时,调用的将是拷贝构造函数,而不是缺省构造函数。在拷贝构造函数中,可以根据传入的变量,复制指针所指向的资源。

  拷贝构造函数的格式为:类名(const类名& 对象名);//拷贝构造函数的原型,参数是常量对象的引用。由于拷贝构造函数的目的是成员复制,不应修改原对象,所以建议使用const关键字

  提供了拷贝构造函数后的CExample类定义为:

class CExample

{

public:

CExample(){pBuffer=NULL;nSize=0;}

~CExample(){delete[]pBuffer;}

CExample(constCExample&); //拷贝构造函数

void Init(int n){pBuffer=new char[n]; nSize=n;}

private:

char *pBuffer; //类的对象中包含指针,指向动态分配的内存资源

int nSize;

};

CExample::CExample(constCExample& RightSides) //拷贝构造函数的定义

{

nSize=RightSides.nSize;//复制常规成员

pBuffer=new char[nSize];//复制指针指向的内容

memcpy(pBuffer,RightSides.pBuffer,nSize*sizeof(char));

}

  这样,定义新对象,并用已有对象初始化新对象时,CExample(const CExample& RightSides)将被调用,而已有对象用别名RightSides传给构造函数,以用来作复制。

此外,当某对象是按值传递时(无论是作为函数参数,还是作为函数返回值),编译器都会先建立一个此对象的临时拷贝,而在建立该临时拷贝时就会调用类的拷贝构造函数

 

赋值操作符的重载

theObjthree=theObjone;

这里也用到了"="号,但与"复制初始化"中的例子并不同。"复制初始化"的例子中,"="在对象声明语句中,表示初始化。更多时候,这种初始化也可用圆括号表示。例如:CExample theObjthree(theObjone);

  而本例子中,"="表示赋值操作。将对象theObjone的内容复制到对象theObjthree,这其中涉及到对象theObjthree原有内容的丢弃,新内容的复制。

  但"="的缺省操作只是将成员变量的值相应复制。由于对象内包含指针,将造成不良后果:指针的值被丢弃了,但指针指向的内容并未释放。指针的值被复制了,但指针所指内容并未被复制。

  因此,包含动态分配成员的类除提供拷贝构造函数外,还应该考虑重载"="赋值操作符号

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值