gpt4 book ai didi

c++ - 这是正确的 : virtual method of Derived called before constructing Base object?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:07:47 27 4
gpt4 key购买 nike

我知道在 Base 类的构造函数中 - 当调用虚拟方法时 - 调用 Base 方法,而不是派生 - 参见 Calling virtual functions inside constructors .

我的问题与这个主题有关。我只是想知道如果我在 Derived 类构造函数中调用虚拟方法会发生什么 - 但在构造 Base 部分之前。我的意思是调用虚方法来评估基类构造函数参数,请参见代码:

class Base {
public:
Base(const char* name) : name(name) {
cout << "Base():" << name << endl;
}
virtual const char* getName() {
cout << "Base::getName()" << endl;
return "Base";
}
protected:
const char* name;
};

class Derived : public Base {
public:
Derived() : Base(getName()) {
cout << "Derived():" << name << endl;
}
virtual const char* getName() {
cout << "Derived::getName()" << endl;
return "Derived";
}
};

int main() {
Derived d;
}

编译器 g++(4.3.x-4.5x 版本)输出为:

Derived::getName()
Base():Derived
Derived():Derived

不过我希望:

Base::getName()
Base():Base
Derived():Base

这看起来没有错 - 但请考虑这个产生段错误的例子:

class Derived : public Base {
public:
Derived() : Base(getName()), name(new string("Derived")) {
cout << "Derived():" << Base::name << endl;
}
virtual const char* getName() {
cout << "Derived::getName()" << endl;
return name->c_str();
}
private:
string* name;
};

请回答:这是正确的 g++ 行为吗? C++ 标准对此有何规定?也许这是未定义的行为?

[更新1]我考虑了罗伯特和奥利的回答——我改变了我的第一个例子。然后它 getName() 被称为“虚拟” - 它会产生段错误。请也回答我对这部分的问题。

const char* virtualGetName(Base* basePtr)
{
return basePtr->getName();
}

class Derived : public Base {
public:
Derived() : Base(virtualGetName(this)) {
cout << "Derived():" << Base::name << endl;
}
virtual const char* getName() {
cout << "Derived::getName()" << endl;
return "Derived";
}
};

最佳答案

您的所有示例都表现出未定义的行为。 C++ 语言标准声明 (C++11 §12.6.2/13):

Member functions (including virtual member functions) can be called for an object under construction. Similarly, an object under construction can be the operand of the typeid operator or of a dynamic_cast.

However, if these operations are performed in a ctor-initializer (or in a function called directly or indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed, the result of the operation is undefined.

您正在从 Derived 类构造函数的初始化列表(ctor-initializer)中调用成员函数 getName()。此成员函数调用必须在 Base 的初始化程序完成之前发生(Basemem-initializer),因为它是初始化程序的参数本身。

因此,行为是未定义的。

通常,Never Call Virtual Functions during Construction or Destruction .

关于c++ - 这是正确的 : virtual method of Derived called before constructing Base object?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11335525/

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