继承中的类作用域(2)

虚函数与作用域

基类与派生类中的虚函数必须有相同的参数列表,假如基类与派生类的虚函数接受的实参不同,则无法通过基类的引用或指针调用派生类的虚函数。

#include 

using namespace std;

class Base
{
public:
    virtual int fcn();
};

int Base::fcn()
{
    cout << "Base中的fcn()被调用了" << endl;
    return 0;
}

class D1 :public Base
{
public:
    //隐藏了基类的fcn,这个fcn不是虚函数
    //D1继承了Base::fcn()的定义       
    //此时,D1拥有两个名为fcn的函数
    int fcn(int);               //形参列表与Base中的fcn不一致
    virtual void f2();          //是一个新的虚函数,在Base中不存在
};

int D1::fcn(int m)
{
    cout << "D1中的fcn(int)被调用了" << endl;
    return m;
}

void D1::f2()
{
    cout << "D1中的f2()被调用了" << endl;
}

class D2:public D1
{
public:
    int fcn(int);       //是一个非虚函数,隐藏了D1::fcn(int)
    int fcn();          //覆盖了Base的虚函数fcn
    void f2();          //覆盖了D1的虚函数f2
};

int D2::fcn()
{
    cout << "D2中的fcn()被调用了" << endl;
    return 0;
}

int D2::fcn(int m)
{
    cout << "D2中的fcn(int)被调用了" << endl;
    return m;
}

void D2::f2()
{
    cout << "D2中的f2()被调用了" << endl;
}

int main()
{

    Base bobj;
    D1 d1obj;
    D2 d2obj;

    Base *bp1 = &bobj;
    Base *bp2 = &d1obj;
    Base *bp3 = &d2obj;

    bp1->fcn();     //虚调用,Base::fcn
    bp2->fcn();     //虚调用,Base::fcn
    bp3->fcn();     //虚调用,D2::fcn
    cout << endl;

    /*--------------------------------------------------------------*/
    D1 *d1p = &d1obj;
    D2 *d2p = &d2obj;
    //bp2->f2();        //错误:Base中没有名为f2的成员
    d1p->f2();      //虚调用,D1::f2()
    d2p->f2();      //虚调用,D2::f2()
    cout << endl;

    /*--------------------------这里调用的都是非虚函数------------------------------------*/
    Base *p1 = &d2obj;  
    D1 *p2 = &d2obj;    
    D2 *p3 = &d2obj;

    //p1->fcn(42);      //错误,Base中没有接受一个int的fcn
    p2->fcn(42);        //静态绑定,调用D1::fcn(int)
    p3->fcn(43);        //静态绑定,调用D2::fcn(int)

    system("pause");
    return 0;
}

测试:

继承中的类作用域(2)_第1张图片

总结:

和普通函数一样,成员函数无论是否是虚函数都能被重载。派生类可以覆盖重载函数的0个或多个实例。

你可能感兴趣的:(C++primer)