在一个定义良好的非构造“对象”上调用非虚拟成员函数?

时间:2013-12-29 20:45:30

标签: c++

在构造函数中,允许调用非虚方法成员函数。

从这个事实可以看出,以下代码是明确定义的吗?

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,p。 66:

“在对象的生命周期开始之前但是在对象将占用的存储之后已经分配了... [t]他的程序有未定义的行为 如果[...]指针用于访问非静态数据成员或调用对象的非静态成员函数“

如果根本没有分配存储,那么调用成员函数应该更加未定义。

我想这里有一个很重要的理由可以让它定义为未定义:https://stackoverflow.com/a/3257755/1419315

1 个答案:

答案 0 :(得分:4)

该代码是未定义的行为。

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

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

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

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