C++成员函数重载、覆盖和隐藏的区别

来源:互联网 发布:电脑弹钢琴的软件知乎 编辑:程序博客网 时间:2024/05/17 00:08
C++成员函数重载、覆盖和隐藏的区别


class Base
{
  public:
void Walk(int x){ cout <<"Base::Walk(int)"<< endl; }
void Walk(float x){cout<<"Base::Walk(float)"<<endl;}
virtual void Run(void){cout<<"Base::Run(void)"<<endl;}


};


class Derived: public Base
{
public:
virtual void Run(void){cout<<"Derived::Run(void)"<<endl;}
};




// 如上关系是: Base::Walk(float)和Base::Walk(int)是函数重载关系
               Derived::Run(void)覆盖了Base::Run(void),而不是虚函数重载


int main()
{
Derived der;
Base *pb = &der;
pb->Walk(20);      // 调用 Base::Walk(int)
pb->Walk(1.2f);    // 调用 Base::Walk(float)
pb->Run();         // 调用 Derived::Run(void)
return 0;
}
如果使用pb->Walk(1.2)的话(即参数为double类型)则编译无法通过
原因是double转换为int和float都是合理的,但两者同时存在导致二义性,编译无法通过


下面介绍重载和覆盖的区别
重载函数被重载的特征:
1. 具有相同的作用域
2. 函数名字相同
3. 参数类型、 顺序或数目不同
覆盖指派生类重新实现基类的成员函数,器特征是:
1. 不同作用域
2. 函数完全相同(包括函数名称和参数列表)
3. 基类函数必须是虚函数


经常听到的“虚函数重载”这一说法是不正确的,应该是覆盖,“虚函数重载”实质上是告诉编译器将函数指针
替换重父类继承下来虚函数列表的对象项而实现,这么觉得还是翻译成覆盖比较合适




class Base
{
  public:
virtual void Walk(float x){ cout <<"Base::Walk(float)"<< endl; }
void Run(float x){cout<<"Base::Run(float)"<<endl;}
void Jump(float x){cout<<"Base::Jump(float)"<<endl;}


};


class Derived: public Base
{
public:
virtual void Walk(float x){ cout <<"Derived::Walk(float)"<< endl; }
void Run(int x){cout<<"Derived::Run(int)"<<endl;}
void Jump(float x){cout<<"Derived::Jump(float)"<<endl;}
};
如上的关系是 Derived::Walk(float)覆盖了函数Base::Walk(float)
             Derived::Run(int) 隐藏了Base::Run(int),Derived::Jump(float)隐藏了Base::Jump(float)
而不是重载(不在同一个作用域内),也不是覆盖,因为函数不是虚函数
class Base
{
  public:
virtual void Walk(){ cout <<"Base::Walk()"<< endl; }
   void Run(float x){cout<<"Base::Run(float)"<<endl;}


};


class Derived: public Base
{
public:
virtual void Walk(int x){ cout <<"Derived::Walk(int)"<< endl; }
void Run(int x){cout<<"Derived::Run(int)"<<endl;}
};


int main()
{
Derived der;
Derived* pd = &der;
pd->Run(1);       // 调用Derived::Run(int)
pd->Run(1.2f);    // 调用Derived::Run(int)   证明Base::Run(float)被隐藏
pd->Walk(1);      //  Derived::Run(int)"
// pd->Walk();编译无法通过,函数被隐藏
Base *pb = &der;
pb->Run(1);       // 调用Base::Run(float)
pb->Run(1.2f);    // 调用Base::Run(float) 
pb->Walk();
// pd->Walk(1);编译无法通过,函数被隐藏
return 0;
}
原创粉丝点击