从构造函数调用虚函数

从构造函数调用虚函数

本文介绍了从构造函数调用虚函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我正在阅读Effective C ++,并有项目9:在构建或销毁期间不要调用虚拟函数。我想知道我的代码是否罚款,即使它违反了这条规则:

Hello I'm reading Effective C++ and there is the "Item 9:Never call virtual functions during construction or destruction". And I'm wondering if mine code is fine even if it breaks this rule:

using namespace std;

class A{
public:
  A(bool doLog){
    if(doLog)
      log();
  }

  virtual void log(){
    cout << "logging A\n";
  }
};


class B: public A{
public:
  B(bool doLog) : A(false){
    if(doLog)
      log();
  }

  virtual void log(){
    cout << "logging B\n";
  }
};


int main() {
  A a(true);
  B b(true);
}

这种方法有什么问题吗?

Is there something wrong with this approach? May I get in trouble when I do something more complicated?

编辑

它接缝了我,大多数答案没有得到我在那里做,他们只是解释了为什么调用虚拟函数从构造函数可能有危险。

It seams to me that most answers didn't get what I did there and they simply explained again why is calling virtual function from constructor potentially dangerous.

我想强调我的程序的输出看起来像这样:

I would like to stress out that output of my program looks like this:

logging A
logging B

所以我得到A记录,当它被构造和B记录。这就是我想要的!但是我问,如果你发现任何错误(潜在的危险)与我的黑客克服在构造函数中调用虚函数的问题。

So I get A logged when it is constructed and B logged when it is constructed. And that is what I want! But I'm asking if You find anything wrong(potentially dangerous) with my "hack" to overcome the problem with calling virtual function in constructor.

推荐答案

这取决于你的意思是罚款。你的程序格式良好,它的行为是明确定义的,所以它不会调用未定义的行为和这样的东西。

It depends on what you mean by "fine". Your program is well-formed, and its behavior is well-defined, so it won't invoke undefined behavior and stuff like that.

但是,看到对虚函数的调用,调用是通过调用由覆盖该函数的最派生类型提供的实现来解决的。

However, one may expect, when seeing a call to a virtual function, that the call is resolved by invoking the implementation provided by the most derived type which overrides that function.

除了在构造期间,对应的子对象尚未构造,因此最导出的子对象是当前正在构造的子对象。结果:调用的调度就像函数不是虚拟的一样。

Except that during construction, the corresponding sub-object has not been constructed yet, so the most derived subobject is the one currently being constructed. Result: the call is dispatched as if the function were not virtual.

这是反直觉的,你的程序不应该依赖这种行为。因此,作为一个文化程序员,你应该习惯避免这种模式,并遵循Scott Meyer的指导方针。

This is counter-intuitive, and your program should not rely on this behavior. Therefore, as a literate programmer, you should get used to avoid such a pattern and follow Scott Meyer's guideline.

这篇关于从构造函数调用虚函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 17:36