C++成员函数重载、覆盖和隐藏的区别
来源:互联网 发布:江小白淘宝 编辑:程序博客网 时间:2024/05/18 00:45
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.2
class Base
{
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)是函数重载关系
int main()
{
Derived der;
Base *pb = &der;
pb->Walk(20);
pb->Walk(1.2f);
pb->Run();
return 0;
}
如果使用pb->Walk(1.2)的话(即参数为double类型)则编译无法通过
原因是double转换为int和float都是合理的,但两者同时存在导致二义性,编译无法通过
下面介绍重载和覆盖的区别
重载函数被重载的特征:
1. 具有相同的作用域
2. 函数名字相同
3. 参数类型、 顺序或数目不同
覆盖指派生类重新实现基类的成员函数,器特征是:
1. 不同作用域
2. 函数完全相同(包括函数名称和参数列表)
3. 基类函数必须是虚函数
经常听到的“虚函数重载”这一说法是不正确的,应该是覆盖,“虚函数重载”实质上是告诉编译器将函数指针
替换重父类继承下来虚函数列表的对象项而实现,这么觉得还是翻译成覆盖比较合适
class Base
{
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)
而不是重载(不在同一个作用域内),也不是覆盖,因为函数不是虚函数
class Base
{
virtual void Walk(){ cout <<"Base::Walk()"<< 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);
pd->Run(1.2f);
pd->Walk(1);
// pd->Walk();编译无法通过,函数被隐藏
Base *pb = &der;
pb->Run(1);
pb->Run(1.2
- 类成员函数的重载、覆盖和隐藏的区别
- 类成员函数的重载、覆盖和隐藏的区别
- 类成员函数的重载、覆盖和隐藏区别
- 类成员函数的重载、覆盖和隐藏区别
- 类成员函数的重载、覆盖和隐藏区别
- 类成员函数的重载、覆盖和隐藏区别
- 类成员函数的重载、覆盖和隐藏区别
- 类成员函数的重载、覆盖和隐藏区别?
- C++成员函数重载、覆盖和隐藏的区别
- 类成员函数的重载、覆盖和隐藏区别?
- 类成员函数的重载、覆盖和隐藏区别?
- 类成员函数的重载、覆盖和隐藏区别?
- 类成员函数的重载、覆盖和隐藏区别?
- C++成员函数重载、覆盖和隐藏的区别
- 类成员函数的重载、覆盖和隐藏区别
- 类成员函数的重载、覆盖和隐藏区别
- 类成员函数的重载、覆盖和隐藏区别?
- 类成员函数的重载、覆盖和隐藏区别
- icc和idbc的用法两点
- oracle 取出30%-60%的数据
- 软件测试的14种类
- mac环境下cmake命令行编译总结
- 启停oracle数据库(linux windows )
- C++成员函数重载、覆盖和隐藏的区别
- java基础学习一
- page指令的各个属性的值
- nosql相关简介
- Objective-c多线程
- foreach的应用
- Android.mk的用法和基础
- DllMain中不当操作导致死锁问题的分析--线程退出时产生了死锁
- 国际象棋走棋步数(Distance on Chessboard)计算程序