关于C++:什么是虚拟类

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页面。