成员函数是否在创建任何对象之前保证就绪?

时间:2009-09-08 00:35:19

标签: c++ pointers

考虑这个例子:

#include <iostream>

class myclass
{
public:
    void print() { std::cout << "myclass"; }
};

int main()
{
    myclass* p = 0x0; // any address

    p->print(); // prints "myclass"
}

我没有通过myclass类型的对象调用成员函数print。相反,我从一个指向内存中随机位置的指针调用它。这是一个定义的行为吗?也就是说,成员函数是否保证在创建myclass类型的任何对象之前执行?

2 个答案:

答案 0 :(得分:11)

取消引用null(0)指针正在调用未定义的行为。该计划可以做任何喜欢的事情,包括按预期工作。

在某种程度上,你在这里得到它,因为print()成员函数没有引用任何成员变量(没有任何成员变量),但编译器仍然可能生成会对你造成崩溃的代码。如果成员函数确实引用了任何成员变量,那么您将严重陷入未定义的行为。可能不值得尝试计算你可以做的事情的范围,因为你正在调用未定义的行为,这可能因编译器,编译器,版本,平台,平台,运行而异。

答案 1 :(得分:2)

您可能会发现更改print()功能可能有助于启发这种情况:

void print() { std::cout << "myclass, this=" << this; }

这将输出C ++ this指针的值,在您的示例中将为0(或您设置p的任何内容)。访问该类的任何数据成员将与解除引用this相同,如果它不指向有效构造的myclass实例,则会导致未定义的行为。

如果将函数声明为virtual

,也会遇到问题
virtual void print() { std::cout << "myclass"; }

该实现可能在崩溃之前不会打印任何内容。原因是编译器生成代码以在调用虚拟函数时查看对象vtable,以发现实际调用的函数。如果没有有效的对象,那很可能会崩溃。