本文共 1835 字,大约阅读时间需要 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++的封装是针对程序设计或作的,所以到达类的层次,而类的实例是运行状态,不再功能范畴之类,从使用角度来说,也无须这么做
转载地址:http://qklxi.baihongyu.com/