深度探索C++对象模型-构造函数语义学
来源:互联网 发布:rj45都有网络变压器吗 编辑:程序博客网 时间:2024/06/05 04:00
default constructor构建
- default constructors在编译器需要的时候产生,区别于程序设计者的需要。以下程序进行说明:
class A(public: int v;);void test(){ A a; //a.v没有初始化,需要设计者自行设计default constructor,编译器并不会合成 if(a.v) //...}
编译器会合成default constructor的四种情况:
-带有default constructor的member class object
-带有default constructor的base class(派生)
-带有virtual base class的class
-带有virtual function的class带有default constructor的member class object
class B{public:B(); //B constructor};class D{public: B b; int v;};void test{ D d; //d.b是member object, class B含有constructor //...}
编译器会为class D合成包含member b初始化的代码。
如果D本身定义了constructor函数,如下:
inline D::D{ v = 0;}
那么合成的constructor函数如下:
inline D::D{ b.B::B(); //增加的代码 v = 0; //user code置于编译器增加代码后面
- 带有virtual function的class
c++对象模型通过vptr指针指向包含virtual function的表Vtbl实现虚函数访问。因此产生一个class object时,我们需要额外初始化vptr(内涵class vtbl地址),这部分编译器合成。
出处:http://www.cnblogs.com/skynet/p/3343726.html - 带有virtual base class的class
class A{public: int i} ;class B : virtual public A;class C : virtual public A;class D : public B,public C;foo(const A *p) {pa->i=0;}void test(){ foo(nwe B); foo(new C);}
编译器无法固定foo()中A::i的实际偏移位置,因此pa的具体类型在执行前位置。所以class D的内存布局中需要一个特殊指针指向其中A的位置。
这部分编译器的constructor和vptr的道理是一样的,只不过virtual base class A本身比较特殊(共享的),需要一个额外指针。
具体参见:http://blog.csdn.net/bluedog/article/details/4711169
copy constructor构建
- 三种明显对使用copy constructor的情况
-明确赋初值
class X; X b;X a = b; //X a(b);
-明确赋初值作为参数传递给某个函数
-函数返回一个class object
- Bitwise and memberwise copy
在没有explicit copy constructor情况下,有时编译器可以通过简单的bitwise copy完成初始化化操作,而无需合成copy constructor。例如;
class Word{public: Word(const char*);private: int cnt; char *str;}Word a("book");Word b(a); //bitwise copy
memberwise or bitwise copy:简单地将内建或者派生的data member从一个object拷贝到另一个object,而不会出错。即该class展现出“bitwise copy semantics”特性。
- 需要合成copy constructor
即该class不满足bitwise copy semantics”特性。有以下四种情况:
-带有copy constructor的member class object
-带有copy constructor的base class member(派生)
-带有virtual function的class
-带有virtual base class的class - 带有virtual function class
如果采用bitwise copy,则object b将指向class D的virtual table,显然不对。所以编译器需要合成class D的copy constructor,明确将object的vptr指向class B的virtual table。
class Base{public: virtual int a();}class Derive: public Base{public: int a();}D d;Base b = d; //需要编译器合成copy constructorD d2 = d; //可以采用bitwise copy
- 带有virtual base class的class
编译器需要为class B合成一个copy constructor,设定object b中virtual base class pointer/offset的初值,有时只是简单确定它没有被消抹。确保正确!
class A{public: int i} ;class B : virtual public A;class C : public B;C c;C c2 = c; //bitwise copy即可B b = c; //将其derived class的某个object作为初值时需要合成
程序转化语义学
- 参数初始化 (函数参数)
例如:
void foo(A a); //函数声明A a;foo(a); //object a作为实参传入实际上是copy constructor过程
其中的一种策略是导入暂时性object,如下。调用一次copy constructor, 函数调用结束,该暂时对象被destructor。另外,foo()函数声明也需要修改如下:
void foo(A &a);
A __tmp0; __tmp0.A::A(a); //调用copy construction //重写foo()函数调用,使用暂时对象, foo(__tmp0); //__tmp0在函数中直接使用
- 返回值的初始化
具体实现也需要引入额外参数。
A foo(){ A x0; //处理x0 return x0;}//具体实现机制A __return;void foo(A &__return){ x0.A::A(); //default constructor //处理X0 __return.A::A(x0); //copy constructor return;}
- 编译器层面优化
即Named Return Value(NRV)优化,NRV优化的目的是减少一次copy constructor。具体如下:
void foo(A &__return){ __return.A::A(); //default constructor //直接处理__return,没有copy constructor return;}
需要注意的是,NRV优化的本质是去掉copy constructor,去掉而非生成它,因此NRV优化的前提是该类有copy constructor。
- 成员初始化队列(Member Initialization List)
写一个constructor时,我们有机会设定class members的值,值得初始化在:1)Member Initialization List 2)constructor 函数体内。
编译器会一一操作initialization list,然后再执行函数体内explicit user code。
initialization list 的执行次序是class 中成员的申明次序,而非initialization中排列顺序。
将成员初始化置于Member Initialization List是一种比较优化的方式。
Word::Word() : _name("hi") {_cnt = 0}//编译器扩张后的程序Word::Word(){ _name.String::String("hi"); //initialization list _cnt = 0; //explicit user code}
下面代码的初始化将导致无法预知的错误,由于i声明在j前面,因此i较j先初始化,而此时j的值无法预知。
class X{ int i; int j;public: X(int val): j(val), i(j){}}
- 深度探索C++对象模型第二章 构造函数语义学
- 深度探索C++对象模型--构造函数语义学
- 深度探索C++对象模型-构造函数语义学
- 《深度探索c++对象模型》学习笔记 - 2 构造函数语义学
- 深度探索C++对象模型系列笔记之第二章:构造函数语义学
- 深度探索C++对象模型----Data语义学
- 深度探索C++对象模型-Data语义学
- 深度探索C++对象模型复习和学习 第二章:构造函数语义学(The Semantics of Constructors)
- 深度搜索C++对象模型 - 构造语义学
- 深度探索C++对象模型第五章 构造、解构、拷贝语义学
- 《深度探索c++对象模型》 学习笔记 - 5 构造、析构、拷贝 语义学
- 《深度探索C++对象模型》:构造函数
- 深度搜索C++对象模型 - 函数语义学
- 深度探索C++对象模型之:成员函数语义学--静态成员函数
- 深度搜索C++对象模型2.2 构造函数语义学-Default Constructor的构造操作
- 深度搜索C++对象模型2.2 构造函数语义学-Copy Constructor的构造操作
- [读书笔记] 深入探索C++对象模型-第二章《构造函数语义学》(上)
- [读书笔记] 深入探索C++对象模型-第二章《构造函数语义学》(中)
- KVO 与KVC
- C++ 设计模式之状态模式的使用
- .NET跨平台机制一(mono for android配置教程)
- NSLayoutConstraint
- 第七周 项目三:第八章知识点思维导图
- 深度探索C++对象模型-构造函数语义学
- 索引碎片修复
- 软件管理培训总结
- IOS尺寸与规范(ICON命名规则)
- 移动构造函数和移动赋值运算符
- 9.2迭代器和迭代器范围
- jQuery 基本知识详解
- Java设计模式——接口隔离原则
- C# 中的委托和事件——http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx