复制构造函数(copy constructor) .
来源:互联网 发布:十个做淘宝九个失败 编辑:程序博客网 时间:2024/05/12 19:27
定义:
只有单个形参,该形参是对本类类型对象的引用(常用const修饰),这样的构造函数成为复制构造函数。
使用方式:
(1)显示使用----用一个同类型的对象初始化该对象时;
(2)隐式使用----将该类型的对象传递给函数或从函数返回该类型对象时。
三种类型的复制构造函数:
*bitwise copy constructor :逐位复制-----默认方式
*合成的 copy constructor :编译器合成----执行逐个成员初始化(memberwise initialize),只完成必要的工作,
*自定义的copy constructor:由类设计者定义------因为有些类必须对复制对象加以控制,如数据成员是指针的情况或者数据成员表示在构造函数中分配的其他资源,或类在创建新对象时必须要做一些特定工作,这时候就需要定义自己的复制构造函数。
关于浅拷贝与深拷贝:
浅拷贝:shllow copy= bitwise copy-----逐位(字节)拷贝(默认情况)
例子:
- <SPAN style="FONT-SIZE: 24px">class Base{
- public:
- int a;
- char ch;
- char* str;
- }
- Base b1;
- b1.a=15;
- b1.ch='c';
- b1.str="string";
- b2=b2;</SPAN>
class Base{public: int a; char ch; char* str;}Base b1;b1.a=15;b1.ch='c';b1.str="string";b2=b2;
现在看看b1和b2的内存布局(不考虑对齐):
可以看到:b1.str和b2.str指向了同一内存空间,即当一方撤销时,另一方将受到影响,故应极力避免这种情况-----深度拷贝
深度拷贝:deep copy = memberwise copy-----挨个成员拷贝
再看b1和b2的内存布局:
此时b1.str和b2.str指向了不同的内存空间,但内容(string)还是一样的。
由于编译器默认是bitwise copy semantics
即如果类中没有明确定义或被编译器合成copy constructor(即memberwise copy),则默认使用bitwise copy形式。
注:以上编译器合成copy constructor和bitwise copy constructor两种情况,均不需要类设计的参与!
那么什么 情况下bitwise copy semantics会失效呢?
有四种情况:
(1)当class内含一个class member object ,而后者的class声明有一个copy constructor 时----被class设计者明确声明或被编译器合成-------递归调用;
(2)当class继承自一个base class,而后者存在一个copy constructor时-----被class设计者明确声明或被编译器合成-------递归调用;
(3)当class声明了一个或多个virtual functions时-------因为此时要考虑类对象中的虚函数表指针vptr的值。
当在同层对象之间进行初始化时,bitwise copy已经够用了(为简化,此时不考虑含有指针成员的情况);
例子:
- <SPAN style="FONT-SIZE: 18px">class ZooAnimal{
- public:
- ZooAnimal();
- virtual ~ZooAnimal();
- virtual void animate();
- virtual void draw();
- .....
- };
- class Bear : public ZooAnimal{
- public:
- Bear();
- void animate();
- void draw();
- virtual void dance();
- ......
- };
- Bear yogi;
- Bear winnie = yogi; //bitwise copy</SPAN>
class ZooAnimal{public: ZooAnimal(); virtual ~ZooAnimal(); virtual void animate(); virtual void draw();.....};class Bear : public ZooAnimal{public: Bear(); void animate(); void draw(); virtual void dance();......};Bear yogi;Bear winnie = yogi; //bitwise copy
其内存布局如下:
但是如果存在:当一个base class object以其derived class 的object内容做初始化操作时,此时若bitwise copy显然会出错,因为其vptr将指向不同的虚表,故此时编译器需要合成copy constrctor,以保证vptr复制操作的安全。合成出来的base class object copy constructor会明确是定object的vptr指向base class object 的vitrual table,而不是直接从右手边的class object 中将其vptr现值拷贝过来。
如:
- <SPAN style="FONT-SIZE: 18px">void draw(const ZooAnimal& zoey )
- {
- zoey.draw();
- }
- ZooAnimal franny = yogi;//发生切割(sliced)行为
- draw(yogi); //调用Bear::draw();
- draw(franny); //调用ZooAnimal::draw()</SPAN><SPAN style="FONT-SIZE: 16px">
- </SPAN>
void draw(const ZooAnimal& zoey ){ zoey.draw();}ZooAnimal franny = yogi;//发生切割(sliced)行为draw(yogi); //调用Bear::draw();draw(franny); //调用ZooAnimal::draw()
其内存布局如下(此时由编译器合成copy constructor):
(4)当class派生自一个继承串链时,其中有一个或多个virtual base classes时。
- 复制构造函数(copy constructor)
- 复制构造函数(copy constructor) .
- 复制构造函数(copy constructor)
- virtual copy constructor(虚复制构造函数)
- 类复制构造函数copy constructor
- C++ Copy Constructor (拷贝构造函数,复制构造函数)
- Return to the Basic - 复制构造函数. (Copy Constructor )
- virtual copy constructor(虚复制构造函数) 与 Proerty模式
- 拷贝构造函数(Copy Constructor)
- C/C++修炼之道01——复制构造函数(copy constructor)
- Copy constructor拷贝构造函数
- 拷贝构造函数 (Copy constructor)
- 构造函数语义学----copy constructor
- 复制构造器——Copy Constructor
- 默认的拷贝构造函数copy constructor
- 关于副本构造函数(Copy Constructor)
- 拷贝构造函数 copy constructor 语意学
- 构造函数(constructor)
- Android 核心分析 之七------Service深入分析
- HTML5高级编程之图形扭曲及其应用一(原理篇)
- 全国工程治理已处分1697名县级 94名厅级干部-工程治理-厅机干部-县级干部
- 几个面试题精选
- linux中fdisk分区方法
- 复制构造函数(copy constructor) .
- VS2008编译的mfc程序在没有安装的机子上运行出现配置错误的问题
- NSAttributedString 详解
- windows 下获取时间函数
- Android设计模式系列(3)--SDK源码之单例模式
- sp_dropdevice
- 到了该自己想一想的时候了
- JAVASCRIP中数字类型解说
- java中“+”和“+=”的的区别