在父类之前构造C++成员类吗?

qdo*_*dot 3 c++ inheritance constructor

在场景中:

class A : public B {
private:
   C m_C; 
public:
   A();
}
Run Code Online (Sandbox Code Playgroud)

A::A() : 
   m_C(5),
   B(m_C) 
{} 
Run Code Online (Sandbox Code Playgroud)

法律?之后会B::B(m_C)被调用C::C(int)吗?如果是这样,我该怎么办才能避免呢?


这是如何实现的:

class MyValidator : public QRegExpValidator {
private:
    QRegExp myRegExp;
public:
    MyValidator(); 
    virtual void fixup(QString &f); 
}

MyValidator::MyValidator() 
    QRegExpValidator(QRegExp("foo")); 
{}

void MyValidator::fixup(QString &f){ 
    // A QRegExp("foo") is also needed here. 
}
Run Code Online (Sandbox Code Playgroud)

我已经发现了

const QRegExp & QRegExpValidator::regExp() const; 
Run Code Online (Sandbox Code Playgroud)

这减轻了我自己引用的需要myRegExp,所以我的特定问题就解决了..

还有什么是最好的模式,如果QRegExpValidator没有这样的功能来检索它的初始化程序..手动管道所有的功能到成员类,而不是继承?

jxh*_*jxh 6

这就是C++ 11标准所说的([class.base.init]/10):

在非委托构造函数中,初始化按以下顺序进行:
- 首先,仅对于派生程度最高的类(1.8)的构造函数,虚拟基类按它们在深度优先左侧出现的顺序进行初始化.正确遍历基类的有向非循环图,其中"从左到右"是派生类base-specifier-list中基类出现的顺序.
- 然后,直接基类按声明顺序初始化,因为它们出现在base-specifier-list中(无论mem-initializers的顺序如何).
- 然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化(同样不管mem-initializers的顺序如何).
- 最后,执行构造函数体的复合语句.
[ 注意:声明顺序的作用是确保以初始化的相反顺序销毁基础和成员子对象.- 结束说明 ]

因此,基类在非静态数据成员之前初始化.如果代码实际上以任何方式使用未初始化的数据,则可能会调用未定义的行为.


在评论中,我们讨论了一个可能的设计问题解决方案是使用has-a而不是is-a.你担心有一个会违反DRY(不要重复自己).

在使用has-a时,有两种方法可以避免WET(写入所有内容(至少两次)).一种是使用转换运算符,允许将对象传递给期望"派生"类型的函数.另一个是使用委托运营商.

class Object { /* ... */ };

class FakeDerivedObject {
    Foo foo;
    Object obj;
    //...

    // conversions
    operator Object & () { return obj; }
    operator const Object & () const { return obj; }
    operator Object * () { return &obj; }
    operator const Object * () const { return &obj; }

    // delegation
    Object * operator -> () { return &obj; }
    const Object * operator -> () const { return &obj; }
};
Run Code Online (Sandbox Code Playgroud)

这样,您就不必"重新实现"底层对象的接口.

FakeDerivedObject d;

d->SomeMethodOfUnderlyingObject();
SomeFunctionThatExpectsUnderlyingObject(d);
Run Code Online (Sandbox Code Playgroud)