是否可以使用空对象指针调用成员函数及访问成员变量

最近在查CWnd::GetSafeHwnd()函数时,顺带发现了一个关于CWnd::GetSafeHwnd()的实现过程的讨论,其中讨论过程涉及到了空指针调用成员函数的问题,恰巧之前工作项目中也有偶遇到相关的知识,因此在此总结一下相关知识。

总结到的相关知识

  1. 空对象指针(NULL)可以正常调用成员函数, 并正常返回值
  2. 空对象指针(NULL)调用成员函数时,如果访问对象的成员变量,会崩溃
  3. 空对象指针(NULL)调用类的虚函数会崩溃
  4. 对于包含虚函数的类,其每个对象指针都含有一个隐藏的成员变量,虚函数表指针vfptr

实验工具

类声明:

class CStringHelper
{
public:
    CStringHelper();
    virtual ~CStringHelper();
    int DoNothing();
    void SetStringFlag();
    virtual int DoVirtualFunc();
protected:
    int m_nStringFlag = 1;
    static int ms_nCommVar;
};

类实现:

#include "StringHelper.h"

int CStringHelper::ms_nCommVar = 100;
CStringHelper::CStringHelper()
{

}

CStringHelper::~CStringHelper()
{

}

int CStringHelper::DoNothing()
{
    int k = 0;
    ++ms_nCommVar;
    return ms_nCommVar;
}

void CStringHelper::SetStringFlag()
{
    int x = DoNothing();
    m_nStringFlag = 2;
}

int CStringHelper::DoVirtualFunc()
{
    int y = DoNothing();
    return y;
}
空对象指针(NULL)可以正常调用成员函数, 并正常返回值
  • 实验过程
    CStringHelper *pStringHelper = NULL;
    pStringHelper->DoNothing();
    pStringHelper->SetStringFlag();
  • 实验结果
    • 调用DoNothing正常
    • 调用SetStringFlag过程中,调用DoNothin正常返回,执行到m_nStringFlag = 2;语句时崩溃
  • 理论支撑
    • 调用普通成员函数时(非静态成员函数),有一个隐藏的参数是this指针,类的普通成员函数的地址在程序开始执行时已经是一个固定的地址了。只有访问类的非静态成员变量时才会使用到this指针(对于成员变量m_nStringFlag其实是this->m_nStringFlag)。只有当访问成员变量时,且传入的this指针为空时才会崩溃。

空对象指针(NULL)调用成员函数时,如果访问对象的成员变量,会崩溃。

  • 同上

空对象指针(NULL)调用类的虚函数会崩溃

  • 实验过程
    CStringHelper *pStringHelper = NULL;
    pStringHelper->DoVirtualFunc();
  • 实验结果
    • 执行到pStringHelper->DoVirtualFunc();语句时崩溃

对于包含虚函数的类,其每个对象指针都含有一个隐藏的成员变量,虚函数表指针vfptr

  • 事实支撑
    • 对于拥有虚函数的每个对象,都有一个默认的隐藏成员变量——虚函数表指针vfptr
      • 从VS的自动变量中可以看出:
        1370668-20190915142202124-851108207.png
        而且,相同的类产生的对象的虚函数表指针vfptr都是相同的(可以从实验结果观察出该事实)
      • 对于没有成员变量,有虚函数的类,因为该对象函数一个虚函数表指针,在32位操作系统下,输出其sizeof,为4:
      class CEmptyClass
      {
      public:
        CEmptyClass();
         virtual ~CEmptyClass();
      };
      顺带一提,如果没有虚函数,sizeof得到的值为1。

转载于:https://www.cnblogs.com/HelloGreen/p/11522263.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值