【发布时间】:2016-06-13 13:51:11
【问题描述】:
我有一个简单的课程:
class B
{
public:
int getData() { return 3; }
};
然后,我用 nullptr 初始化一个指向它的指针:
B *foo{ nullptr };
然后,尝试使用它会带来惊喜:
int t = foo->getData();
而 t 现在是 3。如果不构造类,这怎么可能?是因为 getData() 不使用“this”吗?这打破了我对指针的所有知识。
这是预期的行为吗?我在 Visual Studio 2013 中工作。
【问题讨论】:
-
之所以有效,是因为
foo->getData()等价于getData(foo);,并且被调用者从不取消引用参数。请注意,即使它有效,它在 C++ 中也被归类为 未定义的行为。 -
感谢大家的回答。在我看来,它不应该是未定义的行为,它应该崩溃。从我的角度来看,这是安全问题。如果一个方法接收到一个类的指针并且这个指针是nullptr,我可以使用这个指针来调用一个方法。是的,我知道不能保证它会起作用,但它是你图书馆的一个洞。
-
LeDYoM: "在我看来它不应该是未定义的行为,它应该崩溃。" 请对语言有耐心,阅读 C++ 的设计目标和一点它的历史。
-
@Nawaz 我喜欢 C++ 并且我理解它为什么有效。但这让我很惊讶。这个“特性”违反了你的类可能需要的不变量。是的,有人可以说“如果你不使用这个指针就没有不变量”,但我正在开发一个系统,我在其中断言一个类共享指针不是 nullptr,断言工作,但程序继续(在调试中)并且它工作,所以 assert(class != nullptr) 没用。但我假设这种行为来自 C。我仍然喜欢 C++,让我们在 C++17 中改进它;)
-
LeDYoM:这不是 C++ 中的真正想法。这个想法是允许编译器假设“有符号整数溢出永远不会发生”和“被取消引用的指针具有合法值”。如果您想在取消引用空指针时发生崩溃,那么您应该明确断言它是有效的。如果一些程序没有在这样的事情上不必要地分支,它们的运行速度会快很多倍——在 C++ 中,你不需要为不使用的东西付费,而且大多数程序员不想为此付费,所以在 C++17 中移除这种特殊的未定义行为是不可能的。
标签: c++ c++11 visual-studio-2013 nullptr