在非构造"object"上调用非虚拟成员函数是否定义良好?

Is calling a nonvirtual member function on a non-constructed "object" well-defined?

本文关键字:定义 是否 函数 调用 object 虚拟成员      更新时间:2023-10-16

在构造函数内部,允许调用非虚拟成员函数。

从这个事实来看,下面的代码是定义良好的吗?

struct A {
void foo { std::cout << "Hi there! My address is: " << this; }
};
A * a = nullptr;
a->foo ();

答案

在评论中给出的一些链接和链接页面中给出的链接的帮助下,我现在认为答案可以在中找到

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3035.pdf

§3.8第5段,第66页:

"在对象的生存期开始之前,但在分配了对象将占用的存储之后…程序有未定义的行为如果[…]指针用于访问非静态数据成员或调用对象的非静态成员函数">

然后,如果根本没有分配存储,那么调用成员函数应该更加不明确。

我想这里解释一下为什么不定义它是个好主意的一个重要原因:https://stackoverflow.com/a/3257755/1419315

该代码是未定义的行为。

请注意,在构造函数内部,您还可以调用虚拟成员函数。

有些棘手的部分是在构造函数代码开始之前的成员初始化期间调用虚拟成员函数。仍然有效,但不清楚会发生什么(关键是,在构造函数代码开始之前,对象还不被视为其类的实例,虚拟成员函数会被调度到基类)。

如果在成员初始化列表中使用this,某些编译器会发出警告,因为this指针在该点上的行为会很奇怪(只有在构造函数启动后,它才会开始正常运行)。

代码显然是有效的,因为大多数编译器使用VMT方法进行方法调度,但VMT不需要调用非虚拟方法,因此如果方法代码没有以任何方式取消引用this,那么事情似乎"有效"了。然而,代码似乎在一个实现中(甚至在每个实现中)都能工作,这一事实仍然不能使它成为合法的C++代码。