我遇到过一个问题,在构造函数中,我使用
this
指针,但当时 this
指针恰好为空。
例如:
MyClass::MyClass()
{
// The 'this' pointer happened to be null in this case,
// and the program crashed inside 'm_callbackfunc' because
// it does not handle null input.
m_callbackFunc(this);
}
为什么
this
指针可以为空?什么情况下会发生这种情况?
this
指针可以为NULL的唯一方法是程序中的某些代码表现出未定义的行为。
它可以通过类似的方式来实现
void *place = nullptr;
MyClass *object = new (place) MyClass();
问题在于,这实际上取消了 NULL 指针的引用,因此具有未定义的行为。因此
MyClass
构造函数可能会将 this
设置为 NULL。任何其他影响也是可能的 - 这就是未定义行为的本质。
一些调试器还报告
this
是 NULL 指针。但这实际上并不是 this
为 NULL 的标志。这表明 this
是语言关键字,而不是调试器可以找到的目标文件中具有符号名称的东西。其他一些调试器,当被要求评估 this
时,只是报告当前函数/范围/任何内容中不存在任何具有该名称的内容 - 可能是因为 C++ 编译器通过在机器寄存器中传递值来实现 this
。
如果通过空指针调用类方法,在这种情况下,C++ this 指针可以为 NULL
this
可以为 null。
SomeClass *a = 0;
a->someMethod();//kaboom
虽然你绝对不应该这样做,但在实践中,如果someMethod
不访问任何对象字段,你甚至可以偶然摆脱这种情况而不会崩溃(祝你好运稍后发现)。 (只是不要这样做,好吗?)是否是定义行为完全是一个不同的话题。最有可能的是未定义的行为。
但是,这通常不会在构造函数内发生(我想我只在构造函数中抛出异常时在构造函数中看到 null this 。那是很久以前发生的事情了,所以我什至不记得细节了)。这意味着正在发生一些奇怪的事情。您可能试图将其转换为某些东西,某些东西可能会破坏堆栈,通过不同的线程访问程序变量,等等。根据您提供的大量代码,无法猜测这里的问题是什么。
this
是 nullptr,然后稍后调用它的方法来看看会发生什么。虽然这与开篇文章不同,但它满足主题标题(假设 VS2015 没有骗我)。
这是因为我在代码之外做了一些错误的事情(正如其他人在其他地方提到的那样)。
this
可以为空。
this
被推入堆栈。尝试迭代地重写函数。
class Class
{
public:
void makeThisNull();
};
void Class::makeThisNull()
{
makeThisNull();
}
// run this in a debugger and you will see it crash when this == 0x0 (nullptr)
int main()
{
Class c;
c.makeThisNull();
return 0;
}