C++利用类静态变量,实现伪类对象空指针成功访问含有成员变量的成员函数而不崩溃

场景1:

话不多说, 先看代码:

  • main.cpp
#include <stdio.h>
#include "classA.h"

ClassA *pA = NULL;
int main()
{
    pA->func1();  //成功输出"hello world"
    pA->func2();  //调用了类成员函数,程序崩溃
    return 0;
}
  • classA.h
#include <stdio.h>

class ClassA {
public:
    ClassA();

    void func1();
    void func2();

private:
    int data;
};
  • classA.cpp
#include "classA.h"

ClassA::ClassA(){}

void ClassA::func1()
{ 
    printf("hello world\n"); 
}

void ClassA::func2()
{ 
    data = 10;  //空指针的调用于此处崩溃
    printf("data:%d\n", data);
}
Linux编译和运行(win上IDE请忽略)

编译:
g++ main.cpp classA.cpp -o testA
运行:
./testA

运行结果

图片

讨论

从上面运行结果可以看到:c++类对象为空指针时,可以调用未使用类成员变量的成员函数(func1);但如果成员函数(func2)有使用类成员变量时,则调用该函数会导致程序崩溃。
为什么会产生以上结果可以自行百度一下,相关的博客有很多,这里就不做解释了。


场景2:

以上展示了类对象空指针访问类成员函数的现象,下面讲一下利用类的静态变量实现伪空指针同样的调用,能成功调用操作类成员变量的成员函数而不会产生崩溃。
直接上代码:

  • main.cpp
#include <stdio.h>
#include "classB.h"

ClassB *pB = NULL;
int main()
{
    pB->func1();  //成功输出"hello world"
    pB->func2();  //成功输出"data:10"
    return 0;
}
  • classB.h
#include <stdio.h>

class ClassB {
public:
    ClassB();

    void func1();
    void func2();

private:
    static ClassB obj;
    int data;
};
  • classB.cpp
#include "classB.h"

extern ClassB *pB;
ClassB ClassB::obj;

ClassB::ClassB()
{
    pB = this;
}

void ClassB::func1()
{ 
    printf("hello world\n"); 
}

void ClassB::func2()
{ 
    data = 10; 
    printf("data:%d\n", data);
}
Linux编译和运行(win上IDE请忽略)

编译:
g++ main.cpp classB.cpp -o testB
运行:
./testB

运行结果

这里写图片描述

讨论

本处和场景1上的main.cpp基本上是一致的,但程序的空指针不仅能够成功调用未使用类成员变量的成员函数(func1),也能在调用有使用类成员变量成员函数(func2)而不至于崩溃。

能出现这个结果的原因就是main函数中的指针实际上是伪空指针,其实现主要归功于一个C关键字——extern 和类的静态成员;在类ClassB中,通过添加一个静态类成员然后利用其初始巧妙的将this指针传递给了全局变量pB,从而使pB有指向明确的地址而不是空指针;这也就是称它伪空指针的原因。

另外, 如果将类的构造函数和拷贝构造函数私有,可以不需要设置静态成员函数来获取实例就实现了全局仅有一个实例的单例模式。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值