gpt4 book ai didi

c++ - 从构造函数调用虚函数

转载 作者:可可西里 更新时间:2023-11-01 18:41:42 26 4
gpt4 key购买 nike

我正在阅读 Effective C++ ,还有“第 9 条:永远不要在构造或销毁期间调用虚函数”。我想知道即使我的代码违反了这条规则,它是否还可以:

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);
}

这种方法有问题吗?当我做一些更复杂的事情时,我会遇到麻烦吗?

在我看来,大多数答案都没有得到我在那里所做的,他们只是再次解释了为什么从构造函数调用虚函数有潜在危险。

我想强调一下,我的程序输出如下所示:

logging A
logging B

所以我在构造时记录 A,在构造时记录 B。这就是我想要的!但是我想问您是否发现我的“hack”有任何错误(潜在危险)以克服在构造函数中调用虚函数的问题。

最佳答案

Is there something wrong with this approach?

Bjarne Stroustrup 的回答:

Can I call a virtual function from a constructor?

Yes, but be careful. It may not do what you expect. In a constructor, the virtual call mechanism is disabled because overriding from derived classes hasn't yet happened. Objects are constructed from the base up, "base before derived". Consider:

    #include<string>
#include<iostream>
using namespace std;

class B {
public:
B(const string& ss) { cout << "B constructor\n"; f(ss); }
virtual void f(const string&) { cout << "B::f\n";}
};

class D : public B {
public:
D(const string & ss) :B(ss) { cout << "D constructor\n";}
void f(const string& ss) { cout << "D::f\n"; s = ss; }
private:
string s;
};

int main()
{
D d("Hello");
}

the program compiles and produce

B constructor
B::f
D constructor

Note not D::f. Consider what would happen if the rule were different so that D::f() was called from B::B(): Because the constructor D::D() hadn't yet been run, D::f() would try to assign its argument to an uninitialized string s. The result would most likely be an immediate crash. Destruction is done "derived class before base class", so virtual functions behave as in constructors: Only the local definitions are used - and no calls are made to overriding functions to avoid touching the (now destroyed) derived class part of the object.

For more details see D&E 13.2.4.2 or TC++PL3 15.4.3.

It has been suggested that this rule is an implementation artifact. It is not so. In fact, it would be noticeably easier to implement the unsafe rule of calling virtual functions from constructors exactly as from other functions. However, that would imply that no virtual function could be written to rely on invariants established by base classes. That would be a terrible mess.

关于c++ - 从构造函数调用虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16719460/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com