重温《Inside The C++ Object Model》(2) --Default-Constructo
//constructor/non-constructor的区分
class Foo
{
public:
//Foo():val(0),next(NULL) {}
int val;
Foo *next;
};
void foo_bar()
{
Foo bar;
if ( bar.val && bar.next )
{
cout << bar.val << endl;
printf("%p
",bar.next);
cout << "Un initialization" << endl;
}
else
{
cout << "Initialization" << endl;
}
} “带有Default Constructor” 的 Member Class Object(1)如果class A 内含有1个或1个以上的member-class-object, 那末class A 的每个constructor必须调用每一个member-classes的default-constructor; 编译器会扩大已存在的constructor, 在其中安插1些代码, 使得user-code在被履行前, 先调用必要的default-constructors. (2)C++语言要求以”member-objects 在 class 中的生命次序”来调用各个constructors.
假定有以下类: class Dopey
{
public:
Dopey();
// ... etc ...
};
class Sneezy
{
public:
Sneezy(int);
Sneezy();
// ... etc ...
};
class Bashful
{
public:
Bashful();
// ... etc ...
};
class Snow_White
{
public:
Dopey dopey;
Sneezy sneezy;
Bashful bashful;
// ... etc ...
private:
int mumble;
}; 如果Snow_White没有定义default-constructor, 就会有1个non-trivial-constructor被合成出来, 依序调用Dopey, Sneezy, Bashful的default-constructors. 但是如果Snow_White定义了下面这样的default-constructor: Snow_White::Snow_White() : sneezy(1024)
{
mumble = 2048;
} 它会扩大为: //编译器扩大后的default constructor
//C++伪码
Snow_White::Snow_White() : sneezy(1024)
{
//插入 member class object
//调用其 constructor
dopey.Dopey::Dopey();
sneezy.Sneezy::Sneezy();
bashful.Bashful::Bashful();
//explicit user-code
mumble = 2048;
} ”带有Default Constructor” 的 Base Class在派生类中,如果同时存在member-class-object, 则先调用其base-class-constructor, 而后调用member-class-object的constructor.
”带有1个Virtual Function” 的 Class以下的两种情况: (1)class 声明(或继承)1个virtual-function. (2)class 派生自1个继承串链, 其中有1个或更多的virtual-base-classes. 都会有以下的扩大操作在编译期产生: [1]1个 virtual-function-table(在cfront中被称为vtbl)会被编译器生成, 内放class的virtual-function地址; [2]在每个class-object中, 1个额外的pointer-member(也就是vptr)会被编译器合成出来, 内含相干的class-virtual-function-table(class-vtbl)的地址.
则假定有以下继承关系和代码: void flip(const Widget &widget)
{
widget.flep();
} 则widget.flip()的虚拟引发操作会被重新改写, 以使用widget的 vptr 和 vtbl中的flip()条目: //widget.flip() 中的虚拟引发操作的改变
(*widget.vptr[1]).(&widget); ”带有1个Virtual Base Class” 的 Class假定有以下继承关系与代码: class X
{
public:
virtual void memFunction() const
{
cout << "In X" << endl;
}
};
class A : public virtual X
{
public:
void memFunction() const
{
cout << "In A" << endl;
}
};
class B : public virtual X
{
public:
void memFunction() const
{
cout << "In B" << endl;
}
};
class C : public A,public B
{
public:
void memFunction() const
{
cout << "In C" << endl;
}
};
void foo(const X *px)
{
px -> memFunction();
}
int main()
{
foo(new X);
foo(new A);
foo(new B);
foo(new C);
}
/*
void foo(const X &rx)
{
rx.memFunction();
}
int main()
{
foo(X());
foo(A());
foo(B());
foo(C());
}
*/ 编译器没法固定住foo()当中”经过px而存取的X::memFunction()”的实际偏移位置, 由于px的真正类型可以改变, 编译器必须改变”履行存取操作”的那些代码, 使得X::memFunction()可以延迟至履行才决定下来; 该功能则是靠”在派生类对象中的每个虚基类中安插1个指针(_vbcX [virtual-base-class-X])”完成. 所有”经过reference/pointer来存取1个virtual-base-class”的操作都可以通过相干的指针来完成.则foo()函数可以改写以下: void foo(const X *px)
{
//__vbcX表示由编译器产生的指针,指向virtual-base-class-X
px -> __vbcX -> memFunction();
} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |