【发布时间】:2014-08-21 03:10:52
【问题描述】:
通常从构造函数调用虚函数被认为是不好的做法,因为子对象中的覆盖函数不会被调用,因为对象尚未构造。
但是,请考虑以下类:
class base
{
public:
base() {}
~base() {}
private:
virtual void startFSM() = 0;
};
class derived final : public base
, public fsm_action_interface
{
public:
derived() : base{}
, theFSM_{}
{ startFSM(); }
/// FSM interface actions
private:
virtual void startFSM()
{ theFSM_.start(); }
private:
SomeFSMType theFSM_;
}
在这种情况下,类derived 被标记为final,因此不能存在更多的子对象。因此,虚拟调用将正确解析(到最派生的类型)。
这仍然被认为是不好的做法吗?
【问题讨论】:
-
如果它困扰您,请将实现移至非虚函数中,并让虚函数和构造函数都调用它。
-
@mark 是一个非常有用的问题,我不知道从派生的构造函数调用虚函数在被覆盖的行为中有不同的行为。这种行为在 ISO 标准中是否存在,并且实际上会因编译器而异?另外请注意,虚拟方法是私有的,您可以公开继承。
-
如果一年后你决定
derived不应该是final会发生什么? -
re “通常从构造函数调用虚函数被认为是不好的做法,因为子对象中的覆盖函数将不会被调用,因为对象尚未构造。”,如果你的同伴中是这样的话学生或同事,那么他们需要接受教育。 AFAIK 这不是 C++ 程序员的共同观点。但如果是这样,那么整个 C++ 程序员都需要接受教育。
-
base中的什么方法通常调用startFSM?这似乎是相关的,因此我们可以做出充分有根据的决定。
标签: c++ c++11 constructor virtual-functions dynamictype