在C++中的其他一些指令之后调用基类的构造函数

Luc*_*lon 19 c++ oop class

据我所知,不可能调用基类的构造函数.我知道的唯一方法是:

MyClass::MyClass(/* args */) : Base(/* args */)
{
   // ...
}
Run Code Online (Sandbox Code Playgroud)

但这会在开始时调用构造函数.有没有办法在构造函数中的其他地方调用它?像这样的东西:

MyClass::MyClass(/* args */)
{
   // ... instructions
   Base::Base(/* args */);
   // ... other_instructions
}
Run Code Online (Sandbox Code Playgroud)

根据这个调用超类构造函数的规则是什么?问题我明白没有办法,但我在这里阅读,我猜这是可能的,但如果我尝试我得到:

error: invalid use of 'class Base'.
Run Code Online (Sandbox Code Playgroud)

难道我做错了什么?有可能以某种方式做到这一点还是有其他可能的解决方案来满足这种需求?

谢谢!

编辑:我理解我忘记了一个关键点:基类是框架的一部分,因此如果可能的话,最好不要修改它.

Pau*_*oke 20

如果基类构造函数至少使用一个参数,则可以使用这样的辅助函数:

int DoStuffBeforeCtorAndForwardInt(int arg, Foo foo)
{
    DoStuff(arg, foo);
    return arg;
}

MyClass::MyClass(int arg, Foo foo)
    : Base(DoStuffBeforeCtorAndForwardInt(arg, foo))
{
   // ...
}
Run Code Online (Sandbox Code Playgroud)

如果要对基类进行默认初始化,可以使用copy-ctor复制默认的初始化基类实例:

Base DoStuffBeforeCtorAndReturnDefaultBase(int arg, Foo foo)
{
    DoStuff(arg, foo);
    return Base();
}

MyClass::MyClass(int arg, Foo foo)
    : Base(DoStuffBeforeCtorAndReturnDefaultBase(arg, foo))
{
   // ...
}
Run Code Online (Sandbox Code Playgroud)

或者,如果Base不必是第一个基类,则可以MyClass从辅助类派生:

MyClass::MyClass(/* ... */)
    : DoStuffHelperClass(/* ... */),
    Base(/* ... */)
{
   // ...
}
Run Code Online (Sandbox Code Playgroud)

所有上述要求你所做的"东西"不依赖于即将被初始化的对象(即函数不能安全地成为成员函数,你也不能安全地this作为参数传递给它们).

这意味着您可以执行一些日志记录或类似操作,但在基类初始化之后,您也可以再次执行此操作.

(编辑除了DoStuffHelperClass解决方案,你当然可以在DoStuffHelperClass中有成员,访问它们,什么不是)


虽然我不得不说我不记得曾经使用/需要/想要这样的东西.对于你正在尝试做的事情,很可能还有另一个(更好的)解决方案.


Fre*_*urk 10

使用base-from-member习惯用法在"真正的"基类(Base)的ctor之前运行你的代码:

struct Base {
  Base(string, int);
};

struct DerivedDetail {
  DerivedDetail() {
    value = compute_some_value();
    value += more();
    value += etc();
    other = even_more_code(value);
  }
  string value;
  int other;
};

struct Derived : private DerivedDetail, Base {
  Derived() : Base(value, other) {}
  // In particular, note you can still use this->value and just
  // ignore that it is from a base, yet this->value is still private
  // within Derived.
};
Run Code Online (Sandbox Code Playgroud)

即使您在DerivedDetail中没有您想要的实际成员,这也可以.如果你在Base的ctor之前详细说明你必须做的事情,那么我可以给出一个更好的例子.


Lst*_*tor 8

在构建自己的类开始之前,基类始终是完全构造的.如果需要更改基类的状态,则必须在构造之后明确地执行此操作.

例:

MyClass::MyClass()
{
    // Implicit call to Base::Base()

    int result = computeSomething();
    Base::setResult(result);

    // ... 
}
Run Code Online (Sandbox Code Playgroud)