C++中重载、覆盖和隐藏

一,多态性

1,(1)声明了基类的指针,该指针指向基类,该指针永远调用自己的成员函数,不管函数是否为虚函数。

   (2)声明了派生类的指针,该指针指向该派生类,该指针永远调用自己的成员函数,不管函数是否为虚函数。

   (3)声明了基类的指针,该指针指向任意一个子类对象,该指针调用一个函数(此函数在基类存在,而且在子类中被重新定义),此时编译系统不清楚该调用哪一个函数,而出错。我们可以将该函数设定为虚函数,则程序运行时候,编译系统会知道调用的是基类函数还是子类函数,此即多态。注:如果调用的函数不是虚函数,则调用自己类中的成员函数。如果指针被声明为基类,尽管它指向子类对象,仍然是基类指针。

2,子类重定义父类成员函数方法,被称为覆盖或重写。覆盖的函数都是虚函数。

3,满足虚函数条件或覆盖的特征是:
   (1)不同的范围(分别位于派生类与基类);
   (2)函数名字相同;
   (3)参数相同;
   (4)基类函数必须有virtual 关键字。

二,成员函数重载

成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。

三,成员函数隐藏

看如下代码:

 Base.h

#include <iostream>
using namespace std;

class Base{
public:    
    void fn(int x){
        cout << "Base" << x << endl;
    }
    void fn1(int x){
        cout << "Base1" << x << endl;
    }
};
View Code

SubClass.h

#include <iostream>
using namespace std;

class SubClass :public Base{
public:    
    void fn(float x){
        cout << "SubClass" << x << endl;
    }
    void fn1(int x){
        cout << "SubClass1" << x << endl;
    }
};
View Code

main.cpp

#include <iostream>
#include "A.h"
#include "B.h"
#include "C.h"
using namespace std;

int main()
{
    C c(10);
    cout << c.GetData() << endl;
    cout << c.A::GetData() << endl;
    cout << c.B::GetData() << endl;
    cout << c.C::GetData() << endl;
    cout << c.doGetData() << endl;
    cout << c.A::doGetData() << endl;
    cout << c.B::doGetData() << endl;
    cout << c.C::doGetData() << endl;
    return 0;
}
View Code

 运行结果:

fn()函数不符合虚函数条件,不是虚函数。

从SubClass角度来说,其有void fn(float x)函数,从Base继承了void fn(int x)函数,因此这两个函数在SubClass内应该是重载的,因此主函数中SubClass对象sc,sc.fn(3.1f)应该调用void fn(float x)函数,sc.fn(1)应该调用void fn(int x),但是运行结果显示两个都调用了void fn(float x)函数,这是因为Base中的void fn(int x)函数被隐藏了。

主函数中sc.fn1(2);时候,通过结果知道调用了void fn1(int x)函数,Base中的void fn1(int x)函数被隐藏了。

因此知道符合函数隐藏条件是:

(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏。注意别与重载混淆。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏。注意别与覆盖混淆。

posted on 2013-10-07 21:56  张三的哥哥  阅读(524)  评论(0编辑  收藏  举报