天天看点

C++重载与覆盖的区别

    重载(overload):是指编写一个与已知函数同名但是参数表不同的函数。重载主要属于静态编联范畴,是在编译期就完成地址的分配。

    普通成员函数的重载主要分成三部分:

(1)在一个类中说明重载。

如 show(int a,char b);//在编译期经过编译器修饰后函数名会变成int_char_show

   show(char* c,double d);//在编译期经过编译器修饰后函数名会变成char_double_show

(2)在基类中声明一个函数,在子类中重载这个函数(未声明virtual关键字)(还有一种说法是隐藏,但我认为可以简单的认为是一种特殊的重载更确切,不考虑这个两个函数具有相同的参数),经过编译期之后,有三种编译区分的方法:

1.根据参数特征进行区分。

如  Base: show(int ,int );

    Derived:  show(int ,float);

这两个函数不是一个函数,编译器可以区分

2.根据“::”作用域符进行区分。编译器进行编译时,可根据不同的作用域进行区分重载函数。

如  Base::show( );

    Derived::show( );

3.根据类对象进行区分调用哪一个重载函数。

如  Base b; b.show( );

    Derived d; d.show( );

由上可知,重载只是一种语言特性,与多态无关,与面向对象无关。

    覆盖(override):是指派生类重写基类的虚函数,重写的函数必须具有一致的参数表和返回值。覆盖是一种动态编联。在运行期进行确定所调用的函数地址。

覆盖是与多态密切相关的一种机制,与面向对象有关。

以下通过一个程序来说明重载与覆盖:

#include<iostream>

using namespace std;

class A

{

public:

A(int data = 0):m_data(data){}

virtual int doGetData()

{

return m_data;

}

int GetData()

{

return doGetData();

}

private:

int m_data;

};

class B:public A

{

public:

B(int data = 1):m_data(data){}

int doGetData()

{

return m_data;

}

private:

int m_data;

};

class C:public B

{

public:

C(int data=2):m_data(data){}

private:

int m_data;

};

int main(int argc, char* argv[])

{

C c(10);

cout<<c.GetData()<<endl;

cout<<c.A::GetData()<<endl;

cout<<c.B::doGetData()<<endl;//结果为1,理由同上。

cout<<c.C::GetData()<<endl;//结果为1 ,理由同上。

cout<<c.doGetData()<<endl;//由于C类中未定义虚函数doGetData()的接口,所以会调用父类的接口。结果为1.

cout<<c.A::doGetData()<<endl;//c.A::doGetData(),C类对象会直接调用A类的作用域内的内存空间,直接调用A的doGetData(),结果为0.

cout<<c.C::doGetData()<<endl;//因为C类为重定义该接口,所以调用B类的doGetd(),而B类的doGetData()返回B::m_data,故输出为1.

return 0;

}

继续阅读