C++ this竟然可以是null
Posted Windows开发
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ this竟然可以是null相关的知识,希望对你有一定的参考价值。
什么情况下this的值是null呢?先看下面一段代码。
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的主要内容,如果未能解决你的问题,请参考以下文章