【问题标题】:C++ Calling overwritten function in derived from base classC ++调用从基类派生的覆盖函数
【发布时间】:2016-05-24 05:39:41
【问题描述】:

我有 2 个类,AB,我需要在 B 中覆盖一个函数,以便从 A 的构造函数中调用。这是我已经拥有的:

class A {
    A(char* str) {
        this->foo();
    }

    virtual void foo(){}
}

class B : public A {
    B(char* str) : A(str) {}

    void foo(){
        //stuff here isn't being called
    }
}

我如何从A::A() 获取要在B::foo() 中调用的代码?

【问题讨论】:

  • 不要在构造函数中使用虚函数,在构造B时,先构造A。此时尚未设置 B 的额外方法/变量。所以事情可能会大错特错。

标签: c++ function inheritance polymorphism virtual


【解决方案1】:

我认为您指的是在初始化期间调用 Virtuals 惯用语(也称为初始化期间的动态绑定),所以请看这里,这里解释了所有内容:

  1. https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Calling_Virtuals_During_Initialization
  2. https://isocpp.org/wiki/faq/strange-inheritance#calling-virtuals-from-ctor-idiom

第二个站点有很好的解释,但比第一个要长。

【讨论】:

  • 很遗憾,这对我来说行不通,不过这很有趣,谢谢。
  • 您能解释一下原因吗?也许我可以帮忙。
  • 这对我来说是一个特殊情况,我在基类中的特定构造函数类似于init variables -> make objects -> run loop,所以我尝试使用的函数是创建对象。所以相反,我翻转了我的基类有两个函数init()start(),在函数调用之间我调用makeObjects()
【解决方案2】:

在构造函数中,基类的函数将被调用,而不是被覆盖的版本。这样做的原因是,使用您的示例,A 的构造函数被调用时B 的初始化未完成,因此调用Bfoo 将使用不完整的B 完成例如,如果这被允许的话。

【讨论】:

    【解决方案3】:

    我需要从 A 的构造函数调用 B 中的重写函数

    这种设计在 C++ 中是不可能的:B 对象的order of construction 是首先构造基础 A 子对象,然后在其之上构造 B。

    结果是,在 A 构造函数中,你仍在构造 A 对象:此时调用的任何虚函数都将是 A 的虚函数。只有当 A 构造完成并且 B 构造开始时,才会B 的虚函数生效。

    为了实现你想要的,你必须使用两步模式:1)你构造对象,2)你初始化它。

    【讨论】:

    • 好。我认为这里需要进一步说明,这也解释了为什么这是 C++ 的设计;也就是说,对虚函数的内容及其期望做出假设是很危险的(例如,某些成员已经初始化)。
    • @YamMarcovic Bjarne Stroustrup 在“C++ 的设计与进化”中解释了基优先逻辑的合理性,第 283 页:如果在构造过程中调用覆盖的函数,它将不知道哪些成员无论是否已经构造,每个被覆盖的函数都必须极其谨慎地编写,并为构造函数保留偏执狂。
    • 这正是我的意思——如果不清楚,请见谅。我认为这可能是对答案的一个很好的补充。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 2011-01-08
    • 2021-07-19
    • 2011-06-19
    • 2020-01-16
    • 2011-01-30
    • 2017-07-05
    相关资源
    最近更新 更多