虚函数的重载与访问

本文参考了虚函数的访问控制与多态,在此基础上,通过示例说明了虚函数的重载不受访问控制符的限制,通过指针或者引用可以访问到各个访问控制级别的虚函数。

编译器在决定调用函数时,如果该函数是虚函数才会在运行时确定调用什么函数,如果不是虚函数,那么在编译阶段就已经确定了调用的函数类型。

1. 虚函数的重载不受访问控制符的限制

(1)、 在基类中虚函数是public的,在派生类中可以通过protected、private重载虚函数;
(2) 、在基类中虚函数是private的,在派生类中可以通过protected、public重载虚函数;

2. 通过指针或者引用访问虚函数

(1)、 基类定义虚函数为public,派生类覆盖了该虚函数g(),但是将其声明为protected或private,这样当基类的指针绑定到派生类的对象时,使用该基类指针调用该虚函数时,调用能够成功。
(2)、 基类定义虚函数为private,派生类覆盖了该虚函数f(),但是将其声明为protected或public,这样当基类的指针绑定到派生类的对象时,基类中的友元类,使用该基类指针调用该虚函数时,调用能够成功。

3. 示例

/*
* Microsoft Visual Studio 2015
* 2018.04.05
* Written by Xbn
*/
#include <iostream>
using namespace std;

class Base {
    friend class Pal;
public:
    virtual void g(int i = 0) {
        cout << "g(" << i << ") in Base... " << i << endl;
    }
protected:

private:
    virtual void f(int i = 0) {
        cout << "f(" << i << ") in Base... " << i << endl;
    }
};

class ProtDerived :public Base {
public:

protected:
    void g(int i = 1) override {
        cout << "g(" << i << ") in ProtDerived... " << i << endl;
    }

    void f(int i = 1) override {
        cout << "f(" << i << ") in ProtDerived... " << i << endl;
    }
private:

};

class PubDerived :public Base {
public:
    void f(int i = 2) override {
        cout << "f(" << i << ") in PubDerived... " << i << endl;
    }
protected:

private:
    void g(int i = 2) override {
        cout << "g(" << i << ") in PubDerived... " << i << endl;
    }
};

class Pal {
public:
    void print(Base* b, int i) {
        b->f(i);
    }
};


int main(void) {

    Pal p;

    cout << "\n-------------g() is public, f() is private-------------------" << endl;
    Base b;
    cout << "Direct call public g(): ";
    b.g(10);
    (&b)->g(10);
    p.print(&b, 100);

    cout << "\n-------------g() decrease to protected, f() increase to protected-------------------" << endl;
    ProtDerived prot;
    Base* b1 = &prot;
    b1->g(20);
    p.print(b1, 200);

    cout << "\n-------------g() decrease to private, f() increase to public-------------------" << endl;
    PubDerived pub;
    cout << "Direct call public f(): ";
    pub.f(300);
    Base* b2 = &pub;
    b2->g(30);
    p.print(b2, 300);

    return 0;
}

4. 示例输出结果


-------------g() is public, f() is private-------------------
Direct call public g(): g(10) in Base... 10
g(10) in Base... 10
f(100) in Base... 100

-------------g() decrease to protected, f() increase to protected-------------------
g(20) in ProtDerived... 20
f(200) in ProtDerived... 200

-------------g() decrease to private, f() increase to public-------------------
Direct call public f(): f(300) in PubDerived... 300
g(30) in PubDerived... 30
f(300) in PubDerived... 300

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。