构造函数中的“this”指针在什么情况下为空?

问题描述 投票:0回答:4

我遇到过一个问题,在构造函数中,我使用

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
指针可以为空?什么情况下会发生这种情况?

c++ constructor this null-pointer
4个回答
12
投票

this
指针可以为NULL的唯一方法是程序中的某些代码表现出未定义的行为。

它可以通过类似的方式来实现

  void *place = nullptr;
  MyClass *object = new (place) MyClass();

问题在于,这实际上取消了 NULL 指针的引用,因此具有未定义的行为。因此

MyClass
构造函数可能会将
this
设置为 NULL。任何其他影响也是可能的 - 这就是未定义行为的本质。

一些调试器还报告

this
是 NULL 指针。但这实际上并不是
this
为 NULL 的标志。这表明
this
是语言关键字,而不是调试器可以找到的目标文件中具有符号名称的东西。其他一些调试器,当被要求评估
this
时,只是报告当前函数/范围/任何内容中不存在任何具有该名称的内容 - 可能是因为 C++ 编译器通过在机器寄存器中传递值来实现
this


7
投票

在这种情况下,C++ this 指针可以为 NULL

如果通过空指针调用类方法,

this
可以为 null。

SomeClass *a  = 0;
a->someMethod();//kaboom

虽然你绝对不应该这样做,但在实践中,如果someMethod

不访问任何对象字段,你甚至可以偶然摆脱这种情况而不会崩溃(祝你好运稍后发现)。 (只是不要这样做,好吗?)

是否是定义行为完全是一个不同的话题。最有可能的是未定义的行为。

但是,这通常不会在构造函数内发生(我想我只在构造函数中抛出异常时在构造函数中看到 null this 。那是很久以前发生的事情了,所以我什至不记得细节了)。这意味着正在发生一些奇怪的事情。您可能试图将其转换为某些东西,某些东西可能会破坏堆栈,通过不同的线程访问程序变量,等等。根据您提供的大量代码,无法猜测这里的问题是什么。


3
投票
根据 Visual Studio,当我将对象包装在 unique_ptr 中并且没有正确初始化它时,

this

 是 nullptr,然后稍后调用它的方法来看看会发生什么。

虽然这与开篇文章不同,但它满足主题标题(假设 VS2015 没有骗我)。

这是因为我在代码之外做了一些错误的事情(正如其他人在其他地方提到的那样)。


2
投票
这是一个递归函数吗?如果是的话,当运行时堆栈空间不足时,

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; }
    
© www.soinside.com 2019 - 2024. All rights reserved.