【问题标题】:Undefined reference to vtable while implementing virtual functions [duplicate]实现虚拟功能时对 vtable 的未定义引用 [重复]
【发布时间】:2016-09-24 09:25:12
【问题描述】:

我尝试实现 Jesse Liberty 和 Tim Keogh 的“C++ 编程入门”示例,但在实现纯虚函数时是编译而不是构建。它给出了错误:对'vtable for circle'的未定义引用

我尝试将变量 itsRadius 替换为虚函数 GetItsRadius 以查看它是否可以工作,但它开始在 switch 语句中给我同样的错误,但对于 RectangleSquare 也是一样的circle 的错误和以前一样。

代码如下:

#include <iostream>

using namespace std;

enum BOOL { FALSE, TRUE };

class Shape
{
    public:
        Shape(){}
        ~Shape(){}
        virtual long GetArea() = 0; // error
        virtual long GetPerim()= 0;
        virtual void Draw() = 0;
    private:
};

void Shape::Draw()
{
    cout << "Abstract drawing mechanism!\n";
}

class Circle : public Shape
{
    public:
        Circle(int radius):itsRadius(radius){}
        ~Circle(){}
        long GetArea() { return 3 * itsRadius * itsRadius; }
        long GetPerim() { return 9 * itsRadius; }
        void Draw();
    private:
        int itsRadius;
        int itsCircumference;
};

class Rectangle : public Shape
{
    public:
        Rectangle(int len, int width):
        itsLength(len), itsWidth(width){}
        ~Rectangle(){}
        long GetArea() { return itsLength * itsWidth; }
        long GetPerim() { return 2*itsLength + 2*itsWidth; }
        virtual int GetLength() { itsLength; }
        virtual int GetWidth() { itsWidth; }
        void Draw();
    private:
        int itsWidth;
        int itsLength;
};

void Rectangle::Draw()
{
    for (int i = 0; i<itsLength; i++)
    {
        for (int j = 0; j<itsWidth; j++)
            cout << "x ";

        cout << "\n";
    }
    Shape::Draw();
}

class Square : public Rectangle
{
    public:
        Square(int len);
        Square(int len, int width);
        ~Square(){}
        long GetPerim() {return 4 * GetLength();}
};

Square::Square(int len):
    Rectangle(len,len)
{}

Square::Square(int len, int width):
    Rectangle(len,width)
{
    if (GetLength() != GetWidth())
        cout << "Error, not a square... a Rectangle??\n";
}

void startof()
{
    int choice;
    BOOL fQuit = FALSE;
    Shape * sp;

    while (1)
    {
        cout << "(1)Circle (2)Rectangle (3)Square (0)Quit: \n";
        cin >> choice;

        switch (choice)
        {
            case 1: sp = new Circle(5);
                break;
            case 2: sp = new Rectangle(4,6);
                break;
            case 3: sp = new Square (5);
                break;
            default: fQuit = TRUE;
                break;
        }
        if (fQuit)
            break;

        sp->Draw();
        cout << "\n";
    }
}


int main()
{
    startof();
}

【问题讨论】:

  • @Garf365 - 这是这个问题的有用链接,但我不会称之为重复。这个问题让 OP 寻求一些特定代码的帮助。

标签: c++


【解决方案1】:

这里的问题是你没有定义函数Circle::Draw()。如果你定义它,代码就会编译。

顺便说一句,您应该将Shape 析构函数设为虚拟(否则在某些情况下,派生类的实例可能无法正确销毁)。这里的规则是,如果一个类有 any 个虚拟成员,那么析构函数也应该是虚拟的。

我知道您看到的编译消息非常神秘。我见过这种“未定义的 v-table”编译器错误是其他问题的副作用的场景,就像在这种情况下一样。只是为了让您知道,消除此错误的一个好方法是将受影响类的虚函数定义之一移出线(我使用上面的 Circle 析构函数执行此操作,首先将 Shape 析构函数设为虚拟)。这揭示了更好的编译器错误的真正问题。

【讨论】:

  • 另外,我不认为这是@user5550660 的意图,但如果他们想调用Circle::Draw() 来调用Shape::Draw(),因为它是纯虚拟的,他们需要显式调用Shape::Draw()来自Circle::Draw()的定义。
猜你喜欢
  • 1970-01-01
  • 2011-07-27
  • 2014-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多