重载与覆盖的区别 c++
2011-12-12 09:51
239 查看
这也许会使人联想到函数的重载与覆盖的区别,但稍加对比就会发现两者是完全不同的:
(1) 重载的几个函数必须在同一个类中; 覆盖的函数必须在有继承关系的不同的类中;
(2) 覆盖的函数前必须加关键字Virtual;重载和Virtual没有任何瓜葛,加不加都不影响重载的运作。
(3) 覆盖的几个函数必须函数名、参数、返回值都相同;
重载的函数必须函数名相同,参数不同。参数不同的目的就是为了在函数调用的时候编译器能够通过参数来判断程序是在调用的哪个函数。这也就很自然地解释了为什么函数不能通过返回值不同来重载,因为程序在调用函数时很有可能不关心返回值,编译器就无法从代码中看出程序在调用的是哪个函数了。
#include <iostream.h>
class Base
{
public:
virtual void f(float x){ cout << "Base::f(float) " << x << endl; }
void g(float x){ cout << "Base::g(float) " << x << endl; }
void h(float x){ cout << "Base::h(float) " << x << endl; }
};
class Derived : public Base
{
public:
virtual void f(float x){ cout << "Derived::f(float) " << x << endl; }
void g(int x){ cout << "Derived::g(int) " << x << endl; }
void h(float x){ cout << "Derived::h(float) " << x << endl; }
};
void main(void)
{
Derived d;
Base *pb = &d;
Derived *pd = &d;
// Good : behavior depends solely on type of the object
pb->f(3.14f); // Derived::f(float) 3.14
pd->f(3.14f); // Derived::f(float) 3.14
// Bad : behavior depends on type of the pointer
pb->g(3.14f); // Base::g(float) 3.14
pd->g(3.14f); // Derived::g(int) 3 (surprise!)
// Bad : behavior depends on type of the pointer
pb->h(3.14f); // Base::h(float) 3.14 (surprise!)
pd->h(3.14f); // Derived::h(float) 3.14
}
pb是基类指针,pd是派生类指针,pd的所有函数调用都只是调用自己的函数,和多态性无关,所以pd的所有函数调用的结果都输出Derived::是完全正常的;pb的函数调用如果有virtual则根据多态性调用派生类的,如果没有virtual则是正常的静态函数调用,还是调用基类的,所以有virtual的f函数调用输出Derived::,其它两个没有virtual则还是输出Base::很正常啊,nothing surprise!
记住“只有在通过基类指针或引用间接指向派生类子类型时多态性才会起作用”
包含(或继承)一个或多个纯虚拟函数的类被编译器识别为抽象基类。试图创建一个抽象基类的独立类对象会导致编译时刻错误。
(1) 重载的几个函数必须在同一个类中; 覆盖的函数必须在有继承关系的不同的类中;
(2) 覆盖的函数前必须加关键字Virtual;重载和Virtual没有任何瓜葛,加不加都不影响重载的运作。
(3) 覆盖的几个函数必须函数名、参数、返回值都相同;
重载的函数必须函数名相同,参数不同。参数不同的目的就是为了在函数调用的时候编译器能够通过参数来判断程序是在调用的哪个函数。这也就很自然地解释了为什么函数不能通过返回值不同来重载,因为程序在调用函数时很有可能不关心返回值,编译器就无法从代码中看出程序在调用的是哪个函数了。
#include <iostream.h>
class Base
{
public:
virtual void f(float x){ cout << "Base::f(float) " << x << endl; }
void g(float x){ cout << "Base::g(float) " << x << endl; }
void h(float x){ cout << "Base::h(float) " << x << endl; }
};
class Derived : public Base
{
public:
virtual void f(float x){ cout << "Derived::f(float) " << x << endl; }
void g(int x){ cout << "Derived::g(int) " << x << endl; }
void h(float x){ cout << "Derived::h(float) " << x << endl; }
};
void main(void)
{
Derived d;
Base *pb = &d;
Derived *pd = &d;
// Good : behavior depends solely on type of the object
pb->f(3.14f); // Derived::f(float) 3.14
pd->f(3.14f); // Derived::f(float) 3.14
// Bad : behavior depends on type of the pointer
pb->g(3.14f); // Base::g(float) 3.14
pd->g(3.14f); // Derived::g(int) 3 (surprise!)
// Bad : behavior depends on type of the pointer
pb->h(3.14f); // Base::h(float) 3.14 (surprise!)
pd->h(3.14f); // Derived::h(float) 3.14
}
pb是基类指针,pd是派生类指针,pd的所有函数调用都只是调用自己的函数,和多态性无关,所以pd的所有函数调用的结果都输出Derived::是完全正常的;pb的函数调用如果有virtual则根据多态性调用派生类的,如果没有virtual则是正常的静态函数调用,还是调用基类的,所以有virtual的f函数调用输出Derived::,其它两个没有virtual则还是输出Base::很正常啊,nothing surprise!
记住“只有在通过基类指针或引用间接指向派生类子类型时多态性才会起作用”
包含(或继承)一个或多个纯虚拟函数的类被编译器识别为抽象基类。试图创建一个抽象基类的独立类对象会导致编译时刻错误。
相关文章推荐
- C++中重载、重写(覆盖)和隐藏的区别实例分析
- c++成员函数的重载、覆盖、隐藏区别
- 转载:c++重载、覆盖、隐藏——理不清的区别
- C++重载与覆盖的区别
- C++多态及重载(overload),覆盖(override),隐藏(hide)的区别
- C/C++日常学习总结(第六篇)多基派生引起的虚函数访问二义性问题&重载,覆盖,隐藏的区别
- C++中重定义、重写、重载的区别以及隐藏与覆盖的访问
- C++重载、覆盖和隐藏的区别
- 【C++基础】重载overload、重写(覆盖)override、隐藏hide的区别
- c++成员函数的重载、覆盖、隐藏区别
- C++学习笔记-----继承体系中函数的重载,覆盖和隐藏的区别
- C++中重载、重写(覆盖)和隐藏的区别实例分析
- C++中重载、重写(覆盖)和隐藏的区别
- C++中重载和覆盖的区别
- C++中继承技术引发的问题:重载(overload),覆盖(override)和隐藏(hide)的区别
- C++:类成员函数的重载、覆盖和隐藏区别?
- c++成员函数的重载、覆盖、隐藏区别
- c++中多态函数以及函数重载,覆盖,遮蔽(隐藏)的区别
- C++覆盖、重写、重载的区别
- C++中覆盖、重载和隐藏的区别