多态=虚函数+指针/引用
关于多态:
形状:位置,绘制
矩形:宽度、高度,绘制
圆形:半径,绘制
Shape
/ \
Rect Circle
如果将基类中的某个成员函数声明为虚函数,那么其子类中与该函数具有相同原型的成员函数就也成为虚函数,并对基类中的版本构成覆盖(override)。通过一个指向子类对象的基类指针,或者引用子类对象的基类引用,调用这个虚函数时,实际被调用的将是子类中的覆盖版本。这种特性被称为多态。
关于覆盖
1.基类中成员函数必须是虚函数。
2.子类中成员函数必须与基类中的虚函数拥有完全相同的函数名、形参表和常属性。
3.如果基类中的虚函数返回基本类型,那么子类覆盖版本的返回类型必须与基类完全相同。如果基类中的虚函数返回类类型的指针或者引用,那么子类覆盖版本的返回类型可以是基类返回类型的子类。
class X { … };
class Y : public X { … };
class A {
virtual int foo (void) { … }
virtual X* bar (void) { … }
};
class B : public A {
int foo (void) { … }
Y* bar (void) { … }
};
4.子类中的覆盖版本不能比基类版本抛出更多的异常。
5.子类中覆盖版本与基类版本的访控属性无关。
class A {
public:
virtual int foo (void) { … }
};
class B : public A {
private
int foo (void) { … }
};
B b;
b.foo (); // ERROR !
A* p = &b;
p -> foo (); // OK !
多态的实现离不开基类与子类之间的覆盖关系
示例代码:
#include <iostream>
using namespace std;
class Shape {
public:
Shape (int x, int y) : m_x (x), m_y (y) {}
virtual void draw (void) const = 0;
protected:
int m_x;
int m_y;
};
class Rect : public Shape {
public:
Rect (int x, int y, int w, int h) :
Shape (x, y), m_w (w), m_h (h) {}
void draw (void) const {
cout << "矩形:" << m_x << "," << m_y
<< "," << m_w << "," << m_h << endl;
}
private:
int m_w;
int m_h;
};
class Circle : public Shape {
public:
Circle (int x, int y, int r) :
Shape (x, y), m_r (r) {}
void draw (void) const {
cout << "圆形:" << m_x << "," << m_y
<< "," << m_r << endl;
}
private:
int m_r;
};
void render (Shape* shapes[]) {
for (size_t i = 0; shapes[i]; i++)
shapes[i] -> draw ();
}
int main (void) {
size_t i = 0;
Shape* shapes[1024] = {NULL};
shapes[i++] = new Rect (1, 2, 3, 4);
shapes[i++] = new Rect (5, 6, 7, 8);
shapes[i++] = new Circle (9, 10, 11);
shapes[i++] = new Circle (12, 13, 14);
shapes[i++] = new Rect (15, 16, 17, 18);
render (shapes);
// Shape shape (0, 0);
//virtual 返回类型 函数名 (形参表) = 0;
//的虚函数称为纯虚函数。
//至少含有一个纯虚函数的类,称为抽象类。抽象类不能实例化对象。
return 0;
}
下面是运行结果:
矩形:1,2,3,4
矩形:5,6,7,8
圆形:9,10,11
圆形:12,13,14
矩形:15,16,17,18
本文探讨了C++中的多态性,重点介绍了虚函数和覆盖(override)的概念。多态依赖于虚函数,使得通过基类指针或引用调用子类的方法成为可能。覆盖要求子类函数与基类虚函数有相同的名称、参数列表和返回类型。示例代码展示了多态的使用,输出了不同形状的绘制信息。

4415

被折叠的 条评论
为什么被折叠?



