一、 Overload(重载)
在C++中,函数重载:函数名相同,但参数不同(包括类型、顺序不同),与函数返回值类型无关,例如Example中的f。满足条件:
- 相同的范围(在同一个类中)
- 函数名字相同
- 参数不同
二、Override(覆盖)
在C++中,函数覆盖:对于基类中存在的一个virtual修饰的函数(例如Example中Base类存在g函数),用该基类的指针指向不同子类的类对象(Example的main函数中Base *pb指向Derived d),使用该函数会产生不同的响应结果(结果为子类中所要输出的结果),实际上这也是多态的一种体现,通常也叫做动态绑定。实现原理为:派生类函数覆盖基类函数,类中如果有带virtual关键字修饰的函数,则类中会有一张虚函数表vtable,当基类的virtual 修饰的函数在子类中重新实现后,会将vtable中原基类的函数用新函数来覆盖,若用基类指针指向子类对象时,会指向子类中基类所在的位置,此时基类中的virtual修饰的函数已经被子类实现的所覆盖,所以调用的结果是子类中函数,例如Example中的g。满足条件:
- 不同的范围(分别位于派生类与基类)
- 函数名字相同
- 参数相同
- 基类函数必须有virtual 关键字
三、Overwrite(重写)
重写是指派生类的函数隐藏了与其同名的基类函数。函数为no virtual,只要派生类中存在与基类同名的函数,则发生overwrite,如果有virtual 同名且同参,则发生Override,若同名不同参数发生overwrite。在Example const在派生类中的virtual函数中,同名的普通函数与const函数本质上是两个不同的函数,应该等价理解为这两个同名函数的参数是不同的。
注意发生overwrite,函数行为依赖于指针/引用的类型而不是指向对象的类型。发生override则取决于指向的对象。
四、多态
C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。有了多态,您可以有多个不同的类,都带有同一个名称但具有不同实现的函数,函数的参数甚至可以是相同的。具体为可参考 override 。
Example
#include <iostream>
using namespace std;
class Base
{
public:
void f(int x){ cout << "Base::f(int) " << x << endl; }
void f(float x){ cout << "Base::f(float) " << x << endl; }
virtual void g(void){ cout << "Base::g(void)" << endl;}
};
class Derived : public Base
{
public:
virtual void g(void){ cout << "Derived::g(void)" << endl;}
};
int main()
{
Derived d;
Base *pb = &d;
pb->f(42); // Base::f(int) 42
pb->f(3.14f); // Base::f(float) 3.14
pb->g(); // Derived::g(void)
return 0;
}
Example const
#include <iostream>
using namespace std;
class Base
{
public:
virtual void f(float x){ cout << "Base::f(float) " << x << endl; }
};
class Derived : public Base
{
public:
virtual void f(float x) const { cout << "Derived::f(float) " << x << endl; }//未发生override,而是Overwrite
};
int main()
{
Derived d;
Base *pb = &d;
Derived *pd = &d;
// Bad : behavior depends solely on type of the object
pb->f(3.14f); // Base::f(float) 3.14
pd->f(3.14f); // Derived::f(float) 3.14
return 0;
}
Example 多态
#include <iostream>
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
virtual int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0):Shape(a, b) { }
virtual int area ()
{
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0):Shape(a, b) { }
virtual int area ()
{
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
// 程序的主函数
int main( )
{
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
// 存储矩形的地址
shape = &rec;
// 调用矩形的求面积函数 area
shape->area();
// 存储三角形的地址
shape = &tri;
// 调用三角形的求面积函数 area
shape->area();
return 0;
}