空指针调用成员函数的编译和运行情况

空指针调用成员函数:虚与非虚的区别
文章通过实验展示了空指针调用成员函数在C++中的行为差异。对于非虚成员函数,尽管空指针调用能成功编译,但实际执行时会正常返回。然而,当调用虚函数时,虽然编译无误,但在运行时会出现错误,导致程序异常退出,无法执行函数体内容。

实验内容:空指针调用成员函数(分虚和非虚讨论)的程序编译和运行情况
实验方法:编写一个类A,包含一个成员变量m_a和两个成员函数(非虚函数GetRefA和虚函数fun_v)。声明空指针分别调用虚成员函数和非虚成员函数,观察情况。
实验杰伦:1)非虚成员函数正常调用。原因是在编译器就发生了地址绑定,编译器不会给指针变量分配内存,不知道是空指针,只根据类型找到了对应的成员函数地址并绑定。
2)虚成员函数不能正常调用,尽管编译通过,但是在运行过程中没有正常运行虚函数中的函数体部分,并且程序异常退出,并没有输出第行代码的内容。

总结:空指针调用成员函数在编译阶段可以正常通过。在调用的是虚函数的时候,执行出错;调用非虚函数的时候,正常执行。


#include <iostream>
using namespace std;

class A {
public:
    A() { m_a = 1; }
    ~A() { }

    int GetRefA() {
        std::cout << "GetRefA()运行" << std::endl;
        return m_a;
    }

    virtual void fun_v() {
        std::cout << "fun_v()" << std::endl;
    }

    int m_a;
};

int main() {
    A* a = nullptr;

    // 空指针调用普通成员函数,返回非静态成员
    a->GetRefA();

    // 空指针调用虚成员函数,无法正常运行
    a->fun_v();
    cout << "程序即将退出" << endl;

    return 0;
}

<< 在C++中,默认情况下,空指针直接调用成员函数会导致未定义行为(undefined behavior),这是因为当程序试图访问或操作该空地址时会发生错误。然而,在某些特定的情况下,如果成员函数不引用`this`指针所指向的数据,则可以通过空指针"安全地"调用这些成员函数。 例如静态成员函数以及那些只依赖于传递给它的参数而不涉及实例数据的常量成员函数就可以被看作是可以从空指针调用情况之一,但这是非常危险且不符合编码规范的做法,并不能保证所有编译器都支持这种使用方式。正确的做法是在实际环境中总是确保非静态成员函数调用之前检查对象是否为nullptr。 以下是一些具体的例子: ```cpp #include <iostream> class Example { public: // 静态成员函数 不需要 this 指针即可调用 static void printStatic() { std::cout << "Calling a static member function.\n"; } // 常量成员函数 如果没有引用任何类成员变量也可以由空指针调用(理论上) int getConstValue() const noexcept { return 42; // 这里不会用到 *this 所指向的内容 } }; int main(){ Example* ptr = nullptr; // 安全 - 调用了静态成员函数 ptr->Example::printStatic(); /* 下面这行虽然可以编译运行, 并得到预期的结果, 但是仍然属于非法的操作. */ std::cout<<"Result of calling non-static const method:"<<ptr->getConstValue()<<std::endl; return 0; } ``` ### 解释 - **未定义的行为**:尝试通过空指针访问对象的属性或调用其方法通常会引发崩溃或其他不可预测的问题,因为实际上并没有有效的内存位置与这个空指针关联起来。 - **特殊情况下的“安全性”**: 对于仅基于传入参数工作的成员函数或者完全独立于具体实例状态的方法如静态方法来说,由于它们并不真正关心 `this` 指针指向什么内容,所以即使是从一个无效/为空的对象上来进行这样的调用也可能表面上看起来正常执行,但这并不代表它是正确合法的方式。 - **良好的实践建议**: 总是要先验证指针的有效性再对其做进一步处理;避免任何形式上看似可行但实际上违反语言规则最佳工程习惯写法的现象发生。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值