【问题标题】:Pure virtual "very const" function call from base ctor来自基本 ctor 的纯虚拟“非常 const”函数调用
【发布时间】:2020-08-17 08:59:18
【问题描述】:

我知道禁止从基本 ctor 调用虚拟函数,这是有原因的。但是,如果 func 是“非常 const”,我认为,这些原因变得无关紧要。 “Very const”表示该函数直接替换为常量,如下所示:

Color Derived::getColor() const
{
    return Color(0, 255, 0); // no member usage, no member function calls -
                             // only return
}

(我使用函数是因为我需要它的虚拟性。)我可以告诉编译器这个函数是“非常常量”吗? (它可以让我从 ctor 调用这个函数。)

【问题讨论】:

  • 你试过constexpr Color Derived::getcolor() const吗?
  • 不管你做什么,vtable还没有被基类构造函数中的派生类方法填充
  • @Victor 是的,我试过了,virtual funcs 不能是constexpr,而consexpr 并没有禁止函数读取成员。
  • 从语言的角度来看,从基础构造函数调用虚函数是不被禁止的。它是合法的,并且它的效果是明确的。它几乎总是不是你想要的,所以可能是某些编码指南禁止它。

标签: c++ constructor virtual-functions function-call


【解决方案1】:

如果您从基类构造函数调用虚方法,您将获得基类方法,而不是任何被覆盖的方法。

(实际上,根据具体情况,可能是未定义的行为,但这是通常的实际效果)。

【讨论】:

  • “实际上,这是未定义的行为” - 什么?
  • @StoryTeller-UnslanderMonica 我已经澄清了。
  • 好吧,继续,“取决于具体情况”——这指的是什么情况?也许是纯虚函数?如果是这样,这不是问题,但如果您要提及它,请说清楚。
  • C++ 中的错误是否会导致可预测或未定义的行为对大多数程序员来说没有帮助,因为底线是避免错误。然而,如果一个人没有提到不确定行为的可能性,就会受到挑剔的抱怨。就像有人提到它一样。
  • 另外,我不知道你是如何推断出纯虚函数的考虑不适用于这里的。
【解决方案2】:

可能不是最简单的解决方案,但 CRTP 可以帮助解决此类问题...

template <typename Derived>
struct Base {
    Base() {
        c = getColor();
    }

    int getColor() const {
        return static_cast<const Derived&>(*this).getColor();
    }

    int c;
};

struct D1 : Base<D1> {
    int getColor() const {
        return 1;
    }
};

struct D2 : Base<D2> {
    int getColor() const {
        return 2;
    }
};

【讨论】:

  • 在这种情况下,您还可以创建方法 static constexpr(又名“非常 const”)当然,这仅在静态多态性可能的情况下才有效(从 OPs 问题中不清楚,IMO ...)
猜你喜欢
  • 2012-01-28
  • 1970-01-01
  • 2014-01-04
  • 2020-02-15
  • 1970-01-01
  • 2020-07-02
  • 2019-02-21
  • 1970-01-01
  • 2016-10-21
相关资源
最近更新 更多