博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
什么时候需要定义拷贝构造函数【转】
阅读量:2185 次
发布时间:2019-05-02

本文共 1990 字,大约阅读时间需要 6 分钟。

(转自:)

当没有定义拷贝构造函数时,对象值传递时是位拷贝,但是通常情况下,位拷贝已经能满足我们的要求,是我们不必自己定义拷贝构造函数。

但是什么时候需要自己定义呢?

这里有个简单的规则:如果你需要定义一个非空的析构函数,那么,通常情况下你也需要定义一个拷贝构造函数。

像我们常练习去写一个string类时,会去写个普通构造,拷贝构造,重载赋值运算符=,因为里面有个指针变量char * pBuff,在析构函数中,一般都会将该指针置空,这样的析构就是个非空的析构函数。

 

如果你定义拷贝构造函数时遇到这样的错误:

 no copy constructor available or copy constructor is declared 'explicit'

意味着你的拷贝构造函数的参数不是const 。

而且拷贝构造函数是不能加explicit关键字的!

何谓拷贝?在这里,即类型相同的对象才能称为“拷贝”,既然类型相同,那就不存在什么隐式转换的问题!
只有构造函数的参数类型(单一参数或多参数带有默认值)与当前类类型不同时,才有隐式转换问题。 

explicit是用来防止外部非正规的拷贝构造的。要想不存在传值的隐式转换问题,就可以在变量前加上explicit 关键字。

 

Q:为什么拷贝构造函数的参数类型一般都是const ?

 A:因为复制构造函数是用引用方式传递复制对象,引用方式传递的是地址,因此在构造函数内对该引用的修改会影响源对象。而你在用对象a1构造a2时,自然不希望复制构造函数会改变a1的内容,因此要防止复制构造函数内部修改该引用,所以用const声明。

class A

{
int x;
A(int c){x=c;};
A(const A & c){x=c.x}; // 复制构造函数
}

void main()

{
class A a1(10);
class A a2(a1);  // 在用a1构造a2的时候,你当然不希望a1会被改变。
}
 
Q:在拷贝构造函数中为什么可以访问引用对象的私有变量?
A:所谓访问权限(如public,private),是对“类”来说的,不是对“对象”来说的,private访问权限是其它类不能访问,而非这个类的不同对象不能访问。其实这也非常合理,类是自己设计的,当然自己也就知道类的内部结构,所以没有必要对自己也进行类的“封装”。  
---------------------------------------------------------------  
 
当一个函数想访问某个类的私有成员时,需要在要访问的这个类的定义中声明这个函数是它的友元。(个人建议:尽量不要去使用友元,破坏了封装性)
而当这个函数就属于这个类本身的时候,自然就不用多此一举了.
就是说,一个对象的某个函数可以访问同一个类其他对象的私有成员。
这种问题除了在拷贝构造函数出现以外一般不会那样使用。
---------------------------------------------------------------  
 
结果很显然,如果不能访问,那么私有成员的存在就没有了意义。而对于成员函数中允许访问对象的数据成员,一方面保证了安全性与封装性,另一方面提供方便的操作。第一句话的解释,就是承认只有成员函数可以访问私有成员,这里不涉及友元及派生。这样一来,安全性仍然得到了保证,也完成了封装工作。对于第二句话,试想,如果都得靠接口来实现数据传送,那么操作是否极为不便?既然处于成员函数中,已经保证了足够的安全和封装性,那么这里如果还得借助接口,就有些不合情合理了。作为对数据成员的灵活处理,设计者允许在成员函数中访问对象的私有成员,为使用者提供了很大的方便。这同时也反映了语言的灵活性和原则性。  
---------------------------------------------------------------  
 
私有的权限不是对于类中的各个成员说的,所以本类的成员可以访问本类的私有成员,但是一个对象不是这个类的成员,所以不能访问私有成员,这就是为什么需要getxxx()接口的原因。  
---------------------------------------------------------------  
 
C++的封装是针对程序设计或作的,所以到达类的层次,而类的实例是运行状态,不再功能范畴之类,从使用角度来说,也无须这么做
--------------------- 
作者:SurgePing 
来源:CSDN 
原文:https://blog.csdn.net/suxinpingtao51/article/details/36890809?utm_source=copy 
版权声明:本文为博主原创文章,转载请附上博文链接!

你可能感兴趣的文章
【LEETCODE】303-Range Sum Query - Immutable
查看>>
【LEETCODE】21-Merge Two Sorted Lists
查看>>
【LEETCODE】231-Power of Two
查看>>
【LEETCODE】172-Factorial Trailing Zeroes
查看>>
【LEETCODE】112-Path Sum
查看>>
【LEETCODE】9-Palindrome Number
查看>>
【极客学院】-python学习笔记-Python快速入门(面向对象-引入外部文件-Web2Py创建网站)
查看>>
【LEETCODE】190-Reverse Bits
查看>>
【LEETCODE】67-Add Binary
查看>>
【LEETCODE】7-Reverse Integer
查看>>
【LEETCODE】165-Compare Version Numbers
查看>>
【LEETCODE】299-Bulls and Cows
查看>>
【LEETCODE】223-Rectangle Area
查看>>
【LEETCODE】12-Integer to Roman
查看>>
【学习方法】如何分析源代码
查看>>
【LEETCODE】61- Rotate List [Python]
查看>>
【LEETCODE】143- Reorder List [Python]
查看>>
【LEETCODE】82- Remove Duplicates from Sorted List II [Python]
查看>>
【LEETCODE】86- Partition List [Python]
查看>>
【LEETCODE】147- Insertion Sort List [Python]
查看>>