在非构造"object"上调用非虚拟成员函数是否定义良好?
Is calling a nonvirtual member function on a non-constructed "object" well-defined?
在构造函数内部,允许调用非虚拟成员函数。
从这个事实来看,下面的代码是定义良好的吗?
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++代码。
相关文章:
- 此递归模板类型定义是否有效C++?
- 虚拟成员函数的定义是否强制在同一转换单元中动态初始化静态数据成员?
- 越界成员函数定义是否需要一个完全限定的类名,直到全局范围
- C++标准是否定义了结构中成员函数的函数内定义是否必须具有静态链接?
- 带有"struct structname<..>"的模板定义是否正确?
- NTRUEncrypt:使用开源标准算法中的描述无法正确找到两个多项式的GCD,无法定义是否存在多边形的逆
- 定义重载C++函数模板的原型时,使用其名称引用以前的定义是否合法?
- 命名空间的定义是否可以跨越多个翻译单元
- 头文件中的类声明和定义是否在每个包含上编译
- 这个无括号的C预处理器定义是否安全
- char的实现定义是否会影响std::string
- 对内联函数有不同的定义是否是一种未定义的行为
- 同一字符串的多个#定义是否使用相同的常量字符串
- 根据编译时常量,使用相同的标识符 #define 或类型定义是否被认为是可接受的做法?
- 显式模板实例化定义是否也抑制隐式实例化
- 构造函数定义是否可以以 "class" 关键字为前缀?
- 类中的函数定义是否占用类大小的一部分?
- 名称空间作用域构造函数定义是否需要类限定的标识符
- i=i++;未定义.是否i=foo(i++)也未定义
- "volatile"的定义是否如此不稳定,还是 GCC 存在一些标准合规性问题?