重载默认构造函数导致错误
多年来,我一直在开发C#和Java(在许多其他语言之间),而现在我只是在C++中弄湿了自己的脚。我把自己埋在了继承和类的资源之中,但我似乎无法弄清楚如何摆脱这个令人讨厌的错误。重载默认构造函数导致错误
我的代码:
Entity.h
:
#ifndef ENTITY_H
#define ENTITY_H
#include <iostream>
class Entity
{
public:
std::string m_name;
void update(float delta);
Entity();
private:
virtual void step(float delta);
};
#endif
Entity.cpp
:
#include "Entity.h"
Entity::Entity()
{
m_name = "Generic Entity";
}
void Entity::update(float delta)
{
step(delta);
}
void Entity::step(float delta) {}
Player.h
:
#ifndef PLAYER_H
#define PLAYER_H
#include "Entity.h"
class Player : public Entity
{
public:
Player();
private:
virtual void step(float delta);
virtual void draw() const;
};
#endif
Player.cpp
:
#include "Player.h"
Player::Player()
{
m_name = "Player";
}
void Player::step(float delta) {}
void Player::draw() const {}
Main.cpp
:
int main()
{
return 0;
}
正如你所看到的,我不这样做与类的任何信息,但我发现这些错误:
Error 3 error LNK1120: 1 unresolved externals C:\[...]\Debug\ConsoleApplication1.exe ConsoleApplication11
Error 2 error LNK2019: unresolved external symbol "public: __thiscall Entity::Entity(void)" ([email protected]@[email protected]) referenced in function "public: __thiscall Player::Player(void)" ([email protected]@[email protected]) C:\[...]\ConsoleApplication1\Player.obj ConsoleApplication1
更新:代码奇迹般地工作,当我注释掉Player.cpp
中的以下代码时:
/*Player::Player()
{
m_name = "Player";
}*/
它看起来像实体没有链接到玩家。确保输出显示它编译和他们都添加到您的项目
你还需要在你的基类来定义一个虚析构函数
编辑:
它没有先编译,我的错。在C/C++中,程序创建分两步进行。首先,编译器为您的cpp文件创建obj文件,例如Entity.obj,Player.obj等等。然后链接器会将所有内容捆绑在一起。
在Player.cpp中,你说你在某个时候会有一个名为Entity的类,因此编译器会在.h文件中找到该类的定义。 Player.cpp然后被转换成Player.obj中的可执行代码,但它不包含Entity.obj可执行代码。编译步骤起作用。
然后链接器将尝试解析Player.obj并找到编译器所说的Entity.obj将存在。如果没有,那么你会得到“未定义的引用”错误,因为找到的定义与实际的可执行文件不匹配。
虚拟析构函数是强制性的。 C++的继承方式是使用虚拟表。对于每个具有继承的类,将使用虚拟条目创建一个虚拟表(vtable)。当执行链接步骤时,链接器将使用实际功能填充虚拟表。当代码执行时,它会检查该类的vtable,然后执行该函数。这使您可以“覆盖”基本方法,或者如果没有添加新内容,则使用基本方法。虚拟析构函数在该表中为析构函数创建条目。如果虚拟析构函数没有条目,那么子类将不会有条目,并且将无法正确销毁基类,这会导致未定义的行为
如何编译它?并且私有虚拟方法没有意义 – 2014-11-02 03:30:28
看起来您并未链接“Entity.cpp”的目标代码,很可能是因为您没有编译该文件。还要注意,要使用'std :: string',你应该包含'',而不是''。尽管代码可能与某些编译器一起编译,但它可能无法与其他编译器一起编译。 –
2014-11-02 03:30:34
@BryanChen Microsoft Visual Studio Express 2013 for Windows Desktop – Entity 2014-11-02 03:30:58