问题描述
您好,我正在阅读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.
这篇关于从构造函数调用虚函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!