前言

学习C++函数重写(或函数覆盖)时,发现跟Java有些不一样,这里简单记录一下,方便自己查阅。

正文

下面分别介绍一下。

C++

在C++中,重写并非默认行为,而是需要显式声明的契约。其核心在于区分“重写”与“隐藏”。

重写

只有当基类函数被virtual修饰,且派生类函数签名(名称、参数、const限定符)完全一致时,才构成重写。

C++11引入的override关键字是防御性编程的关键,它强制编译器检查重写合法性,避免因拼写错误或参数不匹配导致的意外隐藏。

动态绑定,调用时由指向的对象决定!

class Base {
public:
    virtual void overrideFunc() {
        cout << "Base::overrideFunc (虚函数)" << endl;
    }
};

class Derived : public Base {
public:
    void overrideFunc() override {
        cout << "Derived::overrideFunc (重写)" << endl;
    }
};

int main() {
    Base* ptr = new Derived();
    // 重写:动态绑定,调用派生类版本
    ptr->overrideFunc();  // 输出: Derived::overrideFunc (重写)
    delete ptr;
    return 0;
}

虚函数,动态绑定,指向了子类,调用子类重写的函数、

隐藏

若基类函数非虚,或派生类函数仅同名但参数不同,则发生隐藏。

隐藏是编译期静态绑定,通过基类指针调用时始终执行基类版本,与对象实际类型无关。

静态绑定:对于非虚函数,编译器在编译期就根据指针/引用的声明类型(即 Base*)决定了调用目标。

class Base {
public:
    void hideFunc() {
        cout << "Base::hideFunc (非虚)" << endl;
    }
};

class Derived : public Base {
public:
    void hideFunc() {
        cout << "Derived::hideFunc (隐藏)" << endl;
    }
};

int main() {
    Base* ptr = new Derived();
    ptr->hideFunc();      // 输出: Base::hideFunc (非虚)
    delete ptr;
    return 0;
}

普通函数,不支持动态绑定。

静态绑定,编译器在编译期就根据指针/引用的声明类型(即 Base*)决定了调用目标函数。

也就是看哪个类声明的,不是看指向的对象类型!

小结
基类函数绑定方式调用依据输出结果
void hideFunc()静态绑定指针声明类型 Base*Base::hideFunc
virtual void hideFunc()动态绑定对象实际类型 DerivedDerived::hideFunc

Java

Java的设计目标是简化面向对象编程,因此消除了C++中的隐藏机制,将所有实例方法默认为虚函数。

对比

场景C++Java
启用多态基类必须加virtual无需任何关键字
防止误写隐藏派生类必须加override推荐加@Override(仅编译检查)
同名不同参触发隐藏,非多态触发重载,非隐藏
访问父类被重写方法Base::func()super.func()

参考文章

  1. AI

  2. C++图书

相关文章

笔友城堡 - 可定义的个人主页

暂无评论

评论审核已启用。您的评论可能需要一段时间后才能被显示。

none
暂无评论...