类的对象构造顺序以及可能会引发的问题的深入分析

1622 人浏览 | 时间: 2015-06-26 21:23:46 | 作者: codexia

    在实际的开发中,将一个类作为另一个类的成员变量,这种用法,实在是太普遍了。也正因为如此,这里隐藏着巨大的危机。说不定在无意之中就中招了,而你却对此一无所知。这是对象构造顺序的一个问题,希望通过本文的讲解可以让你有个深刻的认识,从根本上了解这个问题的来源,并且防患于未然。
    这篇文章,就讲解知识点来说,并没什么好说的。大把的教材上都讲了。我就不讲述这些基础的概念了。我从项目的实际开发的使用中来讲解这个问题。
    在项目中,使用了一个向导程序,和VS的创建项目的向导一样,向导类作为框架类,类中包含了每个向导页的类。这样就形成了以上的类的成员对象的用法。而在构造函数中,需要处理成员对象的初始化,基类的初始化和类本身的初始化。而对于类来说,都是在构造函数中完成的,而这几个类中顺序如何,你是否清楚?还有,this指针你是否清楚?如果都不清楚,在这里很可能会翻船,所以要好好看看。如果非常清楚我这里要说什么,就不必费劲看了。如果想热心检查我的说法是否正确,很欢迎指正,一起学习交流。
    首先说说初始化顺序。基类、类本身、成员对象这三者,顺序如何,我下面仔细的讨论一下。
    先举个实例的代码,便于讲解。代码如下:

class B
{
private:
    Int i ;
public:
    B();
    ~B();
}
B::B()
{
    i = 3;
}


class A:public Base
{
public:
    A();
    ~A();
    B m_b;   
}
A::A()
{
    ...
}
void main()
{
    A a;
}

    以上是基本的类声明。A继承于Base,A类中包含了成员对象m_b。
    以这个例子,来说一下初始化的顺序,以及为什么要这样的顺序初始化。
    在执行完A a;时,a先分配好了内存,然后调用a的构造函数即A()。此时不会有任何问题。初始化的顺序是这样的:构造一个派生类对象时,首先要构造其基类。为什么呢?你可以想想,派生类继承于基类,内存模型也是在基类的基础之上的。还会继承基类的成员变量。基类的部分,在派生类只是拿来即可。派生类中,无法对基类的成员进行初始化。因为在派生类出来之前,基类就已经造好了。我们可以这么来理解。Base类的初始化必然是它自己来完成,否则就不叫初始化了。如果基类不初始化好,派生类也无法从它继承。没有爸妈,怎么有孩子呢?对吧。不管怎么样,按照先初始化基类再初始化派生类是非常自然地。
    那么A类的成员对象B初始化如何理解呢?
    只有在继承关系中,才有父子关系,即派生关系。而B对象作为A对象的一个成员,完全是客串。A类中,完全可以没有B,可以由C来代替。那么也就是说,B既然是来客串的,必然是已经生成好了的。如果没有出生,怎么来客串呢?在A的构造函数中,代表A正在出生。这就意味着,B已经出生好了。假如B的出生在A的构造

请微信扫码阅读。
为防止恶意爬虫,
已开启反爬机制,
理解哟~~~~
标注
评论
站内搜
百度搜
传送到手机
手机扫码,识别文字,完成传送x
加载中...
标注内容x
加载中...
添加标注x
收藏 0 点赞 0

相关阅读