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

本文共 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/

你可能感兴趣的文章
Java多线程(3) - 多线程之死锁
查看>>
Java多线程(4) - 多线程之Volatile关键字、ThreadLocal、Atomic系列类、CAS
查看>>
Java多线程(5) - 多线程之线程通讯(一)(wait、notify、join、yield、sleep区别与应用)
查看>>
Java多线程(6) - 多线程之线程通讯(二)(wait与notify案例、守护线程)
查看>>
什么是项目管理?怎么管?(二)
查看>>
Java多线程(7) - 多线程之线程停止方式
查看>>
Java设计模式(1) - 单例设计模式多种写法
查看>>
Java设计模式(2) - 工厂设计模式
查看>>
Java多线程(8) - 同步(并发)类容器详解(CopyOnWrite容器、ConcurrentMap容器、Queue队列容器)
查看>>
Java设计模式(3) - 多线程并发设计模式 - Future设计模式
查看>>
Java设计模式(5) - 多线程并发设计模式 - 生产者-消费者设计模式多种写法
查看>>
Java多线程(9) - 多线程 - 线程池详解与使用示例
查看>>
Java多线程(10) - 多线程 - CountDownLatch、CyclicBarrier、Semaphore使用示例详解
查看>>
Java多线程(11) - 多线程 - 锁详解:重入锁、公平锁、非公平锁、读写锁、不可重入锁、自旋锁、独享锁、共享锁、互斥锁、悲观锁、乐观锁、分段锁、偏向锁、轻量级锁、重量级锁、CAS算法原理
查看>>
Java网络编程(10) - Netty网络编程常见问题与疑问
查看>>
设置Django连接到Google Cloud SQL(MYSQL)
查看>>
爬虫: 基于Node.js的强大爬虫,能直接发布抓取的文章哦
查看>>
Django学习笔记 扩展User模型
查看>>
Django资料总结
查看>>
Android进阶系列-发布项目到Jcenter
查看>>