【问题标题】:How do I call a derived class method from the base class constructor in C++? [duplicate]如何从 C++ 中的基类构造函数调用派生类方法? [复制]
【发布时间】:2014-11-24 12:57:17
【问题描述】:

我有一个基类和两个派生类。基类构造函数在调用时应该计算一些属性,尽管这些属性取决于派生类的详细信息。为了避免在每个派生类构造函数中重新编写相同的步骤,我在基类构造函数中对这些步骤进行编码,如下例所示。

问题是当我这样做时,基类构造函数不会调用被覆盖的方法。相反,它调用自己的方法。有没有办法解决这个问题?虽然也有道理,但发生这种行为的原因是什么?

来自 C# 背景,这很奇怪,因为它在那里可以很好地工作。在 C# 中,我会使用关键字 base 调用任何基类方法,而 this 将始终调用派生类方法。

例子:

example.h

#define _USE_MATH_DEFINES
#include <math.h>

class Base
{
    public:
        Base(void);
        ~Base(void);
    protected:
        virtual void Method(void);
};


class Derived : public Base
{
    public:
        Derived(void);
        ~Derived(void);
    protected:
        virtual void Method(void);
};

example.cpp

#include <iostream>

Base::Base()
{
    this->Method(); // This calls Base->Method instead of Derived->Method
}

Base::~Base(){}

void Base::Method() // If I remove this, I have an error "externals undefined"
{
    std::cout << "called Base->Method()" << endl;
}

Derived::Derived()
    : Base()
{
    this->Method(); // This obviously calls Derived->Method
}

Derived::~Derived(){}

void Derived::Method()
{
    std::cout << "called Derived->Method()" << endl;
}

main.cpp

int main()
{
    Base* d = new Derived();

    /*
    Outputs:
        called Base->Method()
        called Derived->Method()
    */
}

【问题讨论】:

    标签: c++ inheritance


    【解决方案1】:

    没有办法做到这一点,因为当基类构造函数运行时,对象还不是派生类型的对象。特别是,在派生类中引入的数据成员直到基类构造函数运行后才被初始化——本质上,基类对象的行为就像派生类的数据成员。

    无论如何,您将不得不推迟计算,直到输入派生类的构造函数。如果我理解您要正确执行的操作,最好的方法可能是给基类一个成员函数来进行计算并从派生类的构造函数中调用它。

    【讨论】:

      【解决方案2】:

      构造函数和析构函数是唯一不能使用 virtual 功能的地方。
      因为Derived 对象尚未构建,调用Derived 函数将导致未定义行为。在析构函数的情况下,Derived 对象已经被析构了。

      Bjarne Stroustrup's Technical FAQ page 对此进行了解释。

      剩下的唯一方法是让对象被构造,然后调用Method()

      【讨论】:

      • 你说这是唯一的例外——但是析构函数呢?
      • @ltjax,在析构函数中,virtual 功能启动没有问题。它按预期工作。
      • @molbdnilo,ltjax,你是对的。我错过了那部分。已编辑。
      猜你喜欢
      • 2013-06-23
      • 1970-01-01
      • 2011-03-05
      • 1970-01-01
      • 2019-08-07
      • 2015-08-18
      • 1970-01-01
      • 2016-07-19
      • 2020-11-28
      相关资源
      最近更新 更多