[英]Why i getting unresolved externals error when declaring virtual functions in parent class?
我有这个父类:
enum UI_STATE
{
UI_STATE_SPLASH_SCREEN,
UI_STATE_LOGIN_SCREEN,
UI_STATE_CHARACTER_CREATION_SCREEN,
UI_STATE_CHARACTER_CHOOSE_SCREEN,
UI_STATE_LOADING_SCREEN,
UI_STATE_GAMEPLAY,
UI_STATE_EXIT_REQUESTED,
UI_STATE_UNKNOWN
};
[event_source(native)]
class UserInterface
{
protected:
MyGUI::Gui *mGUI;
public:
static UserInterface *Instance;
UI_STATE UI_CURRENT_STATE;
public:
UserInterface()
{
MyGUI::OgrePlatform* mPlatform = new MyGUI::OgrePlatform();
mPlatform->initialise(BaseObjects::mWindow, BaseObjects::mSceneMgr);
mGUI = new MyGUI::Gui();
mGUI->initialise();
UI_CURRENT_STATE = UI_STATE_UNKNOWN;
}
~UserInterface()
{
mGUI->destroyAllChildWidget();
mGUI->shutdown();
delete mGUI;
mGUI = NULL;
delete Instance;
Instance = NULL;
}
virtual void update();
virtual void GAMEPLAY_SCREEN_ShowTargetBox();
virtual void GAMEPLAY_SCREEN_HideTargetBox();
...//some other methods
}
UserInterface *UserInterface::Instance = NULL;
还有两个子类,其中一个是覆盖这3个虚函数,第二个对这3个函数什么都不做。
孩子1:
#ifndef GameplayScreenInterface_h
#define GameplayScreenInterface_h
#include "UserInterface.h"
#include "ControllableCharacterAdv.h"
class GameplayScreenUserInterface : public UserInterface
{
private:
...
public:
GameplayScreenUserInterface()
{
...
}
void GAMEPLAY_SCREEN_ShowTargetBox()
{
...
}
void GAMEPLAY_SCREEN_HideTargetBox()
{
...
}
void update()
{
UpdateTargetBox();
UpdateCharacterBox();
}
void UpdateCharacterBox()
{
...
}
void UpdateTargetBox()
{
if (...)
{
if (...)
{
...
}
else if (...)
{
...
}
else
{
...
}
}
else
GAMEPLAY_SCREEN_HideTargetBox();
}
};
#endif GameplayScreenInterface_h
和孩子2:
#ifndef LoginScreenInterface_h
#define LoginScreenInterface_h
#include "UserInterface.h"
#include "NetworkManager.h"
class LoginScreenUserInterface : public UserInterface
{
public:
LoginScreenUserInterface()
{
...
}
};
#endif LoginScreenInterface_h
和编译错误:(
Error 9 error LNK1120: 3 unresolved externals
Error 8 error LNK2001: unresolved external symbol "public: virtual void __thiscall UserInterface::GAMEPLAY_SCREEN_HideTargetBox(void)" (GAMEPLAY_SCREEN_HideTargetBox@UserInterface@@UAEXXZ)
Error 7 error LNK2001: unresolved external symbol "public: virtual void __thiscall UserInterface::GAMEPLAY_SCREEN_ShowTargetBox(void)" (GAMEPLAY_SCREEN_ShowTargetBox@UserInterface@@UAEXXZ)
Error 6 error LNK2001: unresolved external symbol "public: virtual void __thiscall UserInterface::update(void)" (?update@UserInterface@@UAEXXZ)
任何人都知道如何摆脱这些错误?
这些不是编译错误,这些是链接错误。 您的源编译正常,但您没有在基类中提供三个虚函数的实现。
当您在类声明中提到成员函数时,您所做的只是声明函数:您告诉编译器函数的名称是什么,它的参数类型是什么,它的返回类型是什么; 这使得编译器很开心。 您仍然需要提供一些实现,或者将函数标记为abstract,以满足链接器。
在您的cpp文件中执行UserInterface
添加以下内容:
void UserInterface::update() {
// default implementation
}
void UserInterface::GAMEPLAY_SCREEN_ShowTargetBox() {
// default implementation
}
void UserInterface::GAMEPLAY_SCREEN_HideTargetBox() {
// default implementation
}
替代方案,如果某些或所有这些虚函数没有默认实现,则在标头中添加= 0
:
virtual void update() = 0;
virtual void GAMEPLAY_SCREEN_ShowTargetBox() = 0;
virtual void GAMEPLAY_SCREEN_HideTargetBox() = 0;
因为您需要为UserInterface::GAMEPLAY_SCREEN_HideTargetBox
定义一个主体(它可能是一个空实现,如果这对您和您的应用程序的逻辑是可行的)。
如果您不想在基类中定义此函数,请将其设为纯虚拟:
virtual void GAMEPLAY_SCREEN_HideTargetBox() = 0;
这将使您的基类UserInterface
抽象(您将无法创建具有UserInterface
类型的对象),并且所有派生类(您想要非抽象的) 必须为此函数定义主体。
PS这些是链接器错误,而不是编译器错误。
真正的快,它是“基础”类和“派生”类(或“子类”),而不是父类和子类。
自从我使用C ++以来已经过了十年,但我认为问题是因为您的LoginScreenUserInterface类没有实现虚拟方法。 如果未覆盖虚方法,则调用基类实现。 由于您没有方法基类实现。 您收到链接错误。 如果您希望拥有一个没有默认实现的虚拟基类,则应通过在结尾添加= 1将其声明为纯虚拟:
virtual void update()= 0;
这会强制任何派生类提供实现。 如果您不想强制派生类提供实现,那么在基类中提供类似{}的内容。
编译器无法通过查看您的源代码来证明没有人会自己实例化父类。 因此,它为父级创建虚方法表,并初始化该表,链接器正在查找父级函数的地址。
为避免这种情况,您需要通过将= 0附加到定义来声明父函数纯虚拟。 这样编译器将自行禁止实例化父类,将NULL放入VMT并且链接器无需查找。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.