c++ - 神秘的编译器错误,可能与使用 "virtual"有关?

标签 c++ gcc virtual undefined

我遇到了这个编译器错误。我有几百行代码,所以我会发布一些我认为可能相关的代码,但你需要告诉我你想看什么。

这是我在编译时得到的错误:

/tmp/ccBE5kZ5.o:game.cpp:(.text+0x1067): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x17a5): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x1ee6): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x2560): undefined reference to `vtable for Person'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: /tmp/ccBE5kZ5.o: bad reloc address 0xc in section `.text$_ZN6WeaponD1Ev[Weapon::~Weapon()]'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: final link failed: Invalid operation
collect2: ld returned 1 exit status

这是我的 Person 类和 Weapon 类的声明,Actor 类是 Person的后代:

class Actor {
public:
virtual void act();
virtual string getName();
virtual void setName(string n);
Actor();
Actor(string n);
virtual ~Actor();
private:
string name;
};


class Person : public Actor {
public:
void act();
virtual void fight(Person enemy);
virtual void takeDamage(double dmg);

// getters and setters
virtual unsigned getX();
virtual void setX(unsigned amt);
virtual unsigned getY();
virtual void setY(unsigned amt);
virtual Weapon getWeapon();
virtual void setWeapon(Weapon w);
virtual Weapon getArmor();
virtual void setArmor(Weapon a);
virtual unsigned getLevel();
virtual void setLevel(unsigned amt);
virtual double getHealth();
virtual void setHealth(double amt);
virtual double getXP();
virtual void setXP(double amt);
Person();
Person(string n);
private:
Weapon wep;
Weapon armor;
double xp;
unsigned level;
double health;
unsigned x;
unsigned y;
};


class Weapon {
public:
double getStrength();
void setStrength(double s);
double getValue();
void setValue(double amt);
double getHealth();
void setHealth(double amt);
string getName();
void setName(string n);
string getType();
void setType(string t);
Weapon();
Weapon(string n, string t, double dmg);
private:
string name;
string type;
double value;
double health;
double strength;
};

最佳答案

您的错误归结为单一定义规则 (ODR) 和语言对程序的要求。特别是要求必须定义使用的每个函数。一个非虚函数被认为是 odr-used 如果它被调用,或者它的地址被占用。所有虚函数都是odr-used,因此必须在您的程序中定义。

回到你程序中的确切错误,这可能是由于 GCC 编译器如何处理虚拟表的生成,这基本上归结为一个简单的规则:虚拟表是在翻译单元中定义的保存类中第一个非内联虚函数的定义。如果所有虚函数都是内联,则将在包含类定义的每个和所有翻译单元中生成 vtable。

在您的情况下,似乎至少有一个虚函数未声明内联 或未在程序中链接的翻译单元之一中定义。如果第一个非内联虚函数是在其中一个翻译单元中定义的,那么就会生成 vtable,并且您会收到一条不同的错误消息,指出任何没有定义的虚函数都缺少定义.

关于c++ - 神秘的编译器错误,可能与使用 "virtual"有关?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10661833/

相关文章:

c++ - 从字符串中提取不同数据类型的变量

gcc - 在使用 GNU 编译器进行编译期间更改 Linux 中 C++ 应用程序的堆栈大小

c - 指向 __attribute__((const)) 函数的函数指针?

c++ - 取消引用 std::shared_ptr<T[]>?

c++ - 尝试读取/写入 Graphviz DAG 值的工作量证明会导致段错误

c++ - 是否可以将 AddressSanitizer 和 ThreadSanitizer 合并到一个版本中?

c++ - 纯虚拟对象是否有指向 vtbl 的指针?

c# - 如何将虚拟属性添加到密封类

c++ - 如何在 C++ 的多重继承上下文中使用来自特定基类的运算符

c++ - Apache Thrift 外部事件循环