C++ this竟然可以是null

Posted Windows开发

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ this竟然可以是null相关的知识,希望对你有一定的参考价值。



什么情况下this的值是null呢?先看下面一段代码。

#include <iostream>using namespace std;
class CDemoClass{public: int GetSafeValue()    { if (this == nullptr) { cout << "great, not crash" << endl; return 0; } else { return this->m_nValue; }    }
private: int m_nValue = 0;};
int main(){ CDemoClass* pDemoClass = nullptr; pDemoClass->GetSafeValue(); return 0;}

这段代码,定义类CDemoClass,类CDemoClass内定义一个成员变量m_nValue,定义一个安全获取m_nValue的成员函数GetSafeValue(),GetSafeValue()内部先判断this是否为null,如果是返回默认值0,否则返回m_nValue值。函数main()定义CDemoClass指针变量pDemoClass,并赋值为nullptr,然后调用pDemoClass的GetSafeValue()方法。运行效果如下图所示:

可知,程序并没有崩溃,GetSafeValue()走到了this==nullptr分支。接下来解释下这里的内幕。

 

成员函数GetSafeValue(),其实跟普通的C函数一样,只不过编译器在编译时会将成员函数GetSafeValue()变为GetSafeValue(CDemoClass* const this)增加this参数,main()函数内pDemoClass->GetSafeValue()变为GetSafeValue(pDemoClass),所以this是成员函数GetSafeValue()的第一个参数,其值就是pDemoClass,如果pDemoClass为nullptr,this自然也为nullptr。所以,要么main()函数执行pDemoClass->GetSafeValue()之前先判断pDemoClass不为nullptr,或如上述代码在访问成员变量前先判断this指针不为nullptr.

 

但是如果将成员函数GetSafeValue()前面加virtual变成虚函数,程序将会崩溃。崩溃的位置不是在GetSafeValue()内部,而是main()函数执行pDemoClass->GetSafeValue(),这里涉及虚函数表,可以阅读寻找答案。

 

从编译后的函数GetSafeValue(CDemoClass* const this),可知this是const变量,所以不能给this指针赋值,相信你也没有这种使用场景。this是编译器在类成员函数隐式加进去的,所以只能在成员函数内部使用,在C函数内是没有this。类静态成员函数(函数前加static关键字)跟C函数没啥区别,编译器不会为它加this参数,所以也不能使用this。

 

我们经常使用this的场景有:

第一,如果成员函数的参数名字与成员变量一样,这时可以用this来区分,比如CDemoClass提供SetValue(int m_nValue)给m_nValue赋值,可以this->m_nValue = m_nValue,由于示例中成员变量已经加前缀m_,参数名称一般不会一样,此处纯粹为了举例。

 

第二,成员函数的返回值为自身对象时返回*this,特别是在对象连续调用成员函数的时候很有用,比如定义类CPoint,有两个成员变量x和y,两个成员函数CPoint& SetX(int)和CPoint SetY(int),就可以这么调:CPoint pt; pt.SetX(10).SetY(20)。

以上是关于C++ this竟然可以是null的主要内容,如果未能解决你的问题,请参考以下文章

C++ 代码片段执行

此 Canon SDK C++ 代码片段的等效 C# 代码是啥?

震惊!struct中竟然也有this指针!

getActivity() 在片段上返回 null?

EasyClick 运行代码片段出Null

EasyClick 运行代码片段出Null