如何在子类构造函数中调用父类构造函数?

3

我搜索了一下,这似乎是在C++中调用超类构造函数的唯一方法:

class SuperClass
{
    public:

        SuperClass(int foo)
        {
            // do something with foo
        }
};

class SubClass : public SuperClass
{
    public:

        SubClass(int foo, int bar)
        : SuperClass(foo)    // Call the superclass constructor in the subclass' initialization list.
        {
            // do something with bar
        }
};

但我想知道,在构造函数体中如何调用超类构造函数而不是初始化列表?

我必须处理子类构造函数的输入,并将复杂处理后的参数传递给超类构造函数,我该如何做到这一点?

2个回答

7
在进入派生类构造函数主体之前,必须运行基类构造函数以初始化基类。成员初始化列表是初始化基类的唯一方法。如果参数具有复杂要求,请使用辅助函数计算参数。
示例:
class SuperClass
{
    public:

        SuperClass(int foo)
        {
            // do something with foo
        }
};

class SubClass : public SuperClass
{
    private:
        static int basehelper(int foo)
        {
            // do complicated things to foo
            return result_of_complicated_things;
        }
    public:

        SubClass(int foo, int bar)
        : SuperClass(basehelper(foo))    // Call the superclass constructor in the subclass' initialization list.
        {
            // do something with bar
        }
};

如果基类参数需要仅在构造派生类时才知道的知识,则必须执行以下操作之一:
  • 重复努力,
  • 找到一种方法来存储帮助程序的结果(可能插入一层抽象)并在构造中稍后应用结果,
  • 修改基类以具有更简单的构造函数并支持两阶段初始化,或者
  • 做完全不同的事情。也许组合优于继承是您的用例的好建议。

1
“basehelper” 应该是静态的(或非成员函数),因为您在对象完全构造之前调用它。 - Kevin

2

你不能这样做。

在你的子类开始之前,你必须先初始化父类部分。因此,你需要在初始化器列表的最前面进行操作。

不过,你可以有一个Superclass::initialize()函数来完成你需要做的事情,然后在你的Superclass构造函数中调用它。


您的意思是“您的子类构造函数可以调用它”吗? - Remy Lebeau
好吧,我想我的意思是两者都可以调用它。 - Joseph Larson
那样做没有太多意义,因为那会导致双重初始化。 - Remy Lebeau
这取决于你的默认构造函数有多复杂。当你真正进入构造函数时,超类已经被构造了。这一部分是无法避免的。你可以选择想要的构造函数,并调用方法进行进一步初始化。 - Joseph Larson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接