您的位置:首页 > 编程语言 > C语言/C++

深度探索C++对象模型--------默认构造函数

2012-12-20 09:53 274 查看
一:默认构造函数的构建

默认构造函数总是在被需要的时候构建出来!!关键字“被需要的时候”!!

class Foo
{
public:
int val;
Foo *next;
};

void foo_bar()
{
Foo bar;
if(bar.val || bar.next)
//do something
}


  上述的代码,编写者意图对象bar中的data member val 和 next 为0。但是编译器没有义务为你初始化为。首先对于堆栈中的变量都不一定会被初始化为0,而是上一次使用的痕迹。

对于Class Foo,如果没有任何的user-declared constructor,那么就会有一个default constructor被暗中声明出来,而一个被暗中声明出来的构造函数将是一个无用的构造函数,所以上面的代码休想正确运行。

所以,在生命class Foo对象bar的时候,编译器确实会隐性的声明默认构造函数,但是这个构造函数是无用的。只有在四种情况下,才会生成有用(nontrival default constructor)的构造函数。

1: 带有"Default Constructor" Member class object。

如果一个class没有任何的constructor,但是包含的member object 确有default construct,那么编译器为这个class隐形生成的构造函数将是nontrival即有用的,并且会在需要的时候调用发生。

2: 带有"Default Constructor" 的 Class Base

如果一个derived class没有任何constructor,但是继承自一个有default constructor的base class,那么这个derived class的构造函数将会是有用的,并且在被需要的时候生成出来,依照继承顺序调用基类的构造函数。

3: 带有一个"virtual function“ 的 Class

class Widget
{
public:
virtual int flip() = 0;
//..
};

void flip(const Widget* widget )
{
widget->flip();
}

void main()
{
Bell bell;
Whistle w;
flip(bell);
flip(w);
}


上述代码中,class Bell 和 Whistle均继承自Widget,在声明bell 和 w的时候,编译器隐形生成的默认构造函数会被调用。因为在基类Widget中有virtual function ,所有带Widget的对象模型中会有指向virtual table 的地址;而在子类class Bell和 Whistle总,这个指针同样需要被制定。

4: 带有一个“virtual base class” 的Class

对于不同的编译器,virtual base class在derived class object中的实现方式差别很大;但是共同点是virtual base class 必须在 derived class object 中的位置,能够在执行期间安置妥当,例如下面的代码:

class X { public int x; };
class A:public virtual X{public int j;};
class B:public virtual X{public float k;}
class C:public A,public B{public float g;};

//无法在编译期间确定x的位置
void foo(const A* pa)
{
pa->x = 1024;
}

void main()
{
foo(new B);
foo(new C);
}


为了在运行期间确定x的位置,我们必须做延迟处理:

void foo(const A* pa) { pa->_vbcX->x = 1024; }

其中_vbcX 即是只想virtual base class的指针, 正如你所想的_vbcX正是在构造函数被调用的时候制定的。所以对于没有默认构造函数的带有virtual base class的class object,编译器会在隐性生成的构造函数中指定!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: