拷贝构造函数会在如下三种情况下调用:
- 以
object 的内容初始化另一个class object 的初值 - 当
object 被当作参数交给某个函数时 - 当函数传回一个
class object 时
Default Memberwise Initialization
如果 class 没有提供一个explicit copy constructor 又当如何?当class object 以相同class 的另一个object 作为初始值,其内部是以所谓default memberwise initialization 手法完成的:
class String {
public:
private:
char *str;
int len;
};
String noun("book")
String verb = noun;
verb.str = noun.str;
verb.len = len;
如果String object 被声明为另一个class 的member
class Word {
public:
private:
int _occurs;
String _word;
};
那么一个Word objet 的Default Memberwise Initialization 会拷贝其内置的member:_occurs .然后再于String member object:_word 身上递归实施memberwise initialiaztion
Bitwise Copy Semantics(位逐次拷贝)
在下面程序片段中
#include "Word.h"
Word noun("book");
void foo() {
Word verb = noun;
}
class Word {
public:
Word(const char *);
~Word(){delete [] str;}
private:
int cnt;
char *str;
};
上述Word 的声明不需要合成一个default copy constructor ,但是如果class Word 声明是这样的
class Word {
public:
Word(const String &);
~Word();
private:
int cnt;
String _word;
};
class String {
public:
String(const char *);
String(const String &);
~String();
private:
char *str;
int len;
};
在这种情况下,编译器必须合成一个拷贝构造函数,以便调用member class String object的拷贝构造函数:
inline Word::word(const Word& wd)
{
str.String::string(wd.str);
cnt = wd.cnt;
}
不要Bitwise Copy Semantics
重新设定Virtual Table的指针
当编译器导入一个vptr 到class 之中时,该class 就不再展现bitwise semantics 了
class ZooAnimal {
public:
ZoomAnimal();
virtual ~ZooAnimal();
virtual void animate();
virtual void draw();
private:
};
class Bear : public ZooAnimal {
public:
Bear();
void animate();
void draw();
virtual void danace();
private:
}
Bear yogi;
Bear winnie = yogi;
yogi会被default Bear constructor 初始化。而在constructor 中,yogi的vptr被设定指向Bear class 的virtual table ;关系如下图:
当base class object 以其derived class 的objet 内容坐初你始化操作时,其vptr 复制操作也必须保证安全
ZooAnimal frany = yogi;
处理Virtual Base Class Subobject
一个class obect 如果以另一个object 作为初始值,而后者有一个virtual class subobject ,那也会使bitwise coopy sematics 失效
|