Inside the C++ Object Model学习笔记[Chap2.2]
来源:互联网 发布:淘宝上装修公司靠谱吗 编辑:程序博客网 时间:2024/05/16 08:14
2.2 Copy Constructor建构操作
2.2.1 调用Copy Constructor的三种情况
1. 用一个类对象的内容对另一个对象作明确的初始化操作,如①;
2. 当对象被当作参数传给某个函数时,如②;
3. 当函数传回一个类对象时,如③;
class X { …… };
void func( X x ) { …… }
X func() {
X xx;
return xx;
}
X x1;
X x2 = x1; //----①
func( x1 ); //----②
func(); //----③
注意:用户定义的拷贝构造函数可以带多参数,如:X::X(const X& x, int = 0);
2.2.2 默认memberwise initialization
在类没有提供一个显式的拷贝构造函数时,当类对象以“相同类的另一个对象”作为初值时,其内部从逻辑上说以所谓的default memberwise initialization方式完成的,也就是说把每一个内建的或派生的数据成员(如数组或指针)的值,从某个对象拷贝一份到另外一个对象,但对于其中的成员类对象,则采用调用该成员类的拷贝构造函数完成(若涉及到派生,那么递归调用其基类的拷贝构造函数),如:
class String {
private:
char* str;
int len;
};
String noun(“book”);
String verb = noun;
Memberwise initialization的意义如下:
verb.str = noun.str;
verb.len = noun.len;
至于什么时候产生默认的拷贝构造函数(指nontrivial类型,而编译器总产生trivial类型的拷贝构造函数),跟默认构造函数的产生一样,编译器只在必要的时候才产生,也就是说类不存在bitwise拷贝语意时(为便于理解,不存在bitwise拷贝语意的四种情况为:类内含有带拷贝构造函数的成员类对象;类所继承的基类含拷贝构造函数;类声明了虚函数;类的继承体系中存在抽象基类,除了以上四种情况,类都存在bitwise语意,在此情况下,编译器默认的拷贝构造函数为trivial类型,只作memberwise意义上的拷贝)。按照thinking in c++中
如果设计者定义了自己的拷贝构造函数,那么就会调用设计者所定义的函数。
2.2.3 bitwise copy
Bitwise copy的意义实际上是逻辑memberwise的具体实现,按照位的方式对类对象中的成员一个一个地拷贝,如:
class Word {
public:
Word( const char* );
~Word() { delete [] str; }
private:
int cnt;
char* str;
};
对于memberwise与bitwise的理解问题,我认为仅仅只是角度不一样,memberwise是从概念上而bitwise从实现上分别说明拷贝构造函数的默认意义。
存在的问题:1. 造成内存泄漏;2. 对同一块内存多次删除问题。
2.2.4 非bitwise copy语意
在以下四种情况下,类不展现bitwise copy语意:(同默认构造函数类似)
1. 类内部含有成员类对象,而后者声明有一个拷贝构造函数(不管是显式声明,还是隐式由编译器合成),如下例:
class String {
public:
String( const char* );
String( const String& ); //显式拷贝构造函数
};
class Word {
public:
Word( const String& ); //构造函数,无显式拷贝构造函数
protected:
int cnt;
String str;
};
对Word类,编译器必须隐式合成一个nontrivial拷贝构造函数:
inline Word::Word( const Word& wd) {
str.String::String( wd.str );
cnt = wd.cnt; //注意合成的拷贝构造函数中,所有成员都会被复制
}
2. 当类所继承的基类存在一个拷贝构造函数时,不管是显式还是隐式情况,如:
class Article : public Word { //Word为1.中定义的类
private:
int num;
};
那么,编译器隐式合成的nontrivial拷贝构造函数如下:
inline Article::Article( const Article& al ) {
str.String::String( al.str );
cnt = al.cnt;
num = al.num;
}
3. 类中声明了一个或多个虚函数时;
如是相同类型的对象相互之间拷贝时,虚函数的vptr由编译器设定vptr为指向该类的vtbl即可(参见书――P55图),如:
class ZooAnimal {
public:
virtual ~ZooAnimal();
virtual void animate();
virtual void draw();
};
class Bear : public ZooAnimal {
public:
void animate();
void draw();
virtual void dance();
};
Bear b;
Bear b1 = b; //vptr指向Bear的vtbl。
ZooAnimal za = b; //发生切割问题,并且vptr的指向应该为ZooAnimal的vtbl。
但如果是派生类对象拷贝给基类对象时(会存在切割问题),vptr的复制操作必须保证指向正确的vtbl,即拷贝给基类的vptr必须重新由编译器设置为指向基类的vtbl,而不是派生类的vtbl(参见书――P56图)。这种情况下,显然bitwise的拷贝操作不可能做到。
4. 类的继承体系中,所继承的类有一个或多个抽象基类时。
同上一种情况类似,需要重新设置vptr的指向问题,也存在切割问题。
- Inside the C++ Object Model学习笔记[Chap2.2]
- Inside the C++ Object Model学习笔记[Chap2.1]
- Inside the C++ Object Model学习笔记[Chap2.3]
- Inside the C++ Object Model学习笔记[Chap2.4]
- Inside The C++ Object Model学习笔记
- Inside the C++ Object Model学习笔记[Chap1.2]
- Inside The C++ Object Model 学习笔记 -- 关于对象
- Inside the C++ Object Model学习笔记[Chap1.1]
- Inside the C++ Object Model学习笔记[Chap1.3]
- Inside the C++ Object Model学习笔记[Chap3.0]
- Inside the C++ Object Model学习笔记[Chap3.1-3.3]
- Inside the C++ Object Model学习笔记[Chap3.4]
- Inside the C++ Object Model学习笔记[Chap3.5-3.6]
- Inside the C++ Object Model学习笔记[Chap4.0-4.2]
- Inside the C++ Object Model学习笔记[Chap4.3-4.4]
- Inside the C++ Object Model学习笔记[Chap5]
- Inside the C++ Object Model学习笔记[Chap6]
- 转:Inside the C++ Object Model学习笔记[Chap6]
- Inside the C++ Object Model学习笔记[Chap1.3]
- Inside the C++ Object Model学习笔记[Chap2.1]
- 用winsock编的客户端与服务端在本地运行时,互相之间的通信是否过网卡的问题
- 什么是Web 2.0
- Vista之初体验
- Inside the C++ Object Model学习笔记[Chap2.2]
- Inside the C++ Object Model学习笔记[Chap2.3]
- Inside the C++ Object Model学习笔记[Chap2.4]
- 2006-9-4工作报告(By snail)
- Inside the C++ Object Model学习笔记[Chap3.0]
- Inside the C++ Object Model学习笔记[Chap3.1-3.3]
- Inside the C++ Object Model学习笔记[Chap3.4]
- 一个奇怪的隐藏文件
- HTML中几个Tag比较有用,平时大家用得比较少,而且是符合W3C XHTML标准的。