【问题标题】:What good is virtual in a class? [duplicate]虚拟在课堂上有什么好处? [复制]
【发布时间】:2011-04-04 00:24:21
【问题描述】:

可能重复:
C++ Virtual/Pure Virtual Explained

例如我有:

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);
};

这个虚拟有什么好处?

【问题讨论】:

  • 这是一种非常懒惰的格式。将您的代码缩进四个空格,并正确布局。
  • 或突出显示代码并使用“101010”按钮。
  • 这一定是大量重复。

标签: c++ oop virtual


【解决方案1】:

这是为了诱导多态行为,这意味着客户端可以使用单个合约来调用不同的行为,而客户端不必知道所有可能的行为。

A* a = new B();
a->n(); // Will call B::n();

作为一个更具体的例子,这里有一些相当老套的代码:

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();
    }
}

(免责声明:以上代码既不正确也不完整,当然不能作为好的图形代码的例子。只是为了说明虚函数什么时候有用。

【讨论】:

  • 别听这家伙的,他只是想迷惑你。
  • @Noah:你说的是马塞洛,还是其他一些已经被删除的评论?
  • 也就是说我可以同时当机械师和警察?
  • @tdp 这是编程,你制定规则,你选择是否有意义
  • -1:该代码比典型代码更刻板。
【解决方案2】:

我向您推荐这个关于 polymorphism 的优秀 SO 页面。

【讨论】:

    【解决方案3】:

    我喜欢以国际象棋游戏为例:

    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() 方法。

    【讨论】:

    • 所以这意味着它总是回到主类?
    • @tdp:是的。即使指针循环是 ChessPiece 指针,因为 Move() 方法是虚拟的,它总是会返回到正确的派生类型并使用该版本的 Move() 方法。即 Queen::Move() 或 Castle::Move() 或 Knight::Move() 等
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-30
    • 2016-11-20
    相关资源
    最近更新 更多