What good is virtual in a class?
本问题已经有最佳答案,请猛点这里访问。
Possible Duplicate:
C++ Virtual/Pure Virtual Explained
例如,我有:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class A { private: int i; int j; public: void k (int l, int m) { i=l; j=m; } virtual int n (void); }; class B : public A { public: int n (void); }; |
这个虚拟有什么好处?
我喜欢以国际象棋为例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class ChessPiece { public: virtual int Move() = 0; }; class Queen: public ChessPiece { public: virtual int Move() { /* STUFF */ } }; bool AICode() { int bestMove = 0; foreach(ChessPiece* loop = board.Pieces().begin(); loop != board.Pieces().end(); ++loop) { bestMove = max(bestMove, loop->Move()); } } |
aicode()不需要知道它在看哪个片段。它所做的就是让这首曲子看看它的最佳动作是什么。虚拟调度机制将计算出工件的类型并调用正确的move()方法。
它是诱导多态行为,这意味着一个客户可以使用一个契约来调用不同的行为,而不需要客户了解每一种可能的行为。
1 2 | A* a = new B(); a->n(); // Will call B::n(); |
作为一个更具体的例子,这里有一些相当典型的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | struct Shape { GLfloat transform_[4][4]; void render() const { glPushMatrix(); glMultMatrixf(&transform_[0][0]); draw(); glPopMatrix(); } virtual void draw() const = 0; }; struct Line : public Shape { GLfloat x1, y1, x2, y2; void draw() { glBegin(); glVertex2f(x1, y1); glVertex2f(x2, y2); glEnd(); } }; struct Square : public Shape { GLfloat size; void draw() { GLfloat f = size/2; glBegin(); glVertex2f(-f, -f); glVertex2f( f, -f); glVertex2f( f, f); glVertex2f(-f, f); glVertex2f(-f, -f); glEnd(); } }; void renderShapes(Shape* shapes, int nShapes) { for (int i = 0; i < nShapes; ++i) { shapes[i]->render(); } } |
(免责声明:上述代码既不正确,也不完整,不能作为良好图形代码的例子。这只是为了说明虚拟函数何时有用。
我指的是这个关于多态性的非常好的so页面。