神秘的编译器错误,可能与使用“虚拟”有关
Cryptic compiler error, maybe to do with use of "virtual"?
我收到这个编译器错误。我有几百行代码,所以我会发布一些我认为可能相关的代码,但你需要告诉我你想看到什么。
这是我在编译时收到的错误:
/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
类的声明,以及Person
所属的Actor
类:
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 使用。所有虚函数都是 odr 使用的,因此必须在程序中定义。
回到程序中的确切错误,这可能是由于GCC编译器如何处理虚拟表的生成,这基本上归结为一个简单的规则:虚拟表在转换单元中定义,该转换单元保存类中第一个非内联虚函数的定义。如果所有虚函数都是内联的,那么 vtable 将在包含类定义的每个和所有翻译单元中生成。
似乎在您的情况下,至少有一个虚拟函数没有在程序中链接的翻译单元中声明内联或定义。如果第一个非内联虚函数是在其中一个转换单元中定义的,那么 vtable 就会生成,并且您将收到一条不同的错误消息,说明缺少任何没有定义的虚函数的定义。
这是说Person
中有virtual
字段未定义。到目前为止,我们可以看到您的声明,但看不到定义。检查是否定义了Person
中的每个虚拟字段,包括继承的虚拟字段。
相关文章:
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 虚拟决赛作为安全
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- 如何在C++中获得"静态纯虚拟"功能?
- C++无法定义虚拟函数 OUTER 类和头文件
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 尝试将lambda函数放在队列中时出现一般分配器错误(可能是与unique_ptr有关的错误)
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 大小虚拟继承中的派生类
- 链接器找不到在虚拟类 c++ 中访问的静态字段的符号
- 有关 c++ 构造函数的问题
- 使用 C++ 和 i2c 工具从虚拟 i2c 写入和读取
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 从 Rcpp Catch 测试中获取有关"inst/extdata"的数据
- 有关继承层次结构的问题,没有任何虚拟功能
- 有关C 虚拟继承的问题
- 神秘的编译器错误,可能与使用“虚拟”有关