简体   繁体   中英

Why i getting unresolved externals error when declaring virtual functions in parent class?

I have this 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;

Also have two child classes, one of those is overrides this 3 virtual functions and second do nothing with this 3 functions.

Child 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

and Child 2:

#ifndef LoginScreenInterface_h
#define LoginScreenInterface_h

#include "UserInterface.h"
#include "NetworkManager.h"

class LoginScreenUserInterface : public UserInterface
{
public:
    LoginScreenUserInterface()
    {
...
    }
};

#endif LoginScreenInterface_h

And compilation errors :(

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)

Anyone have any idea how to get rid of that errors?

These are not compilation errors, these are link errors. Your sources compiled fine, but you did not supply implementations of the three virtual functions in the base class.

When you mentioned a member function in a class declaration, all you did was declaring the function: you told the compiler what's the name of the function, what are its parameter types, and what's its return type; this makes the compiler happy. You still need to supply some implementation, or mark the functions abstract, in order to satisfy the linker.

In your cpp file with the implementation of UserInterface add these:

void UserInterface::update() {
    // default implementation
}
void UserInterface::GAMEPLAY_SCREEN_ShowTargetBox() {
    // default implementation
}
void UserInterface::GAMEPLAY_SCREEN_HideTargetBox() {
    // default implementation
}

Alternativelt, if there is no default implementation for some or all of these virtual functions, add = 0 in the header:

virtual void update() = 0;
virtual void GAMEPLAY_SCREEN_ShowTargetBox() = 0;
virtual void GAMEPLAY_SCREEN_HideTargetBox() = 0;

Because you need to define a body for UserInterface::GAMEPLAY_SCREEN_HideTargetBox (it could be an empty implementation, if this is OK for you and your application's logic).

If you don't want to have definition for this function in the base class, make it pure virtual:

virtual void GAMEPLAY_SCREEN_HideTargetBox() = 0;

This will make your base class UserInterface abstract (you will not be able to create objects with type UserInterface ) and all derived classes (that you want to be non-abstract) must define body for this function.

PS These are linker errors, not compiler errors.

Real quick, it is "base" class and "derived" class (or "sub class"), not parent and child class.

It has been a decade since I worked on C++ but I believe the issue is because your LoginScreenUserInterface class does not implement the virtual methods. If a virtual method is not overridden, then the base class implementation is called. Since you do not have a method base class implementation. You are getting a link error. If you want to have a virtual base class without a default implementation, you should declare it as pure virtual by add an = 1 to the end:

virtual void update() = 0;

That would force any derived class to provide an implementation. If you don't want to force the derived class to provide an implementation, then provide something like { } in the base class.

The compiler cannot prove by looking at your source that no one will ever instantiate the parent class by itself. Therefore, it creates virtual method table for the parent, and to initialize that table, the linker is looking for the addresses of the parent's functions.

To avoid this, you need to declare the parent functions pure virtual by appending =0 to the definition. This way the compiler will prohibit the instantiation of parent class by itself, will put NULLs into VMT and the linker have nothing to look for.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM