Unresolved External Symbol how to fix it? abstract class - c++

Here's my abstract class Storestate.h:
#ifndef STORESTATE_H_
#define STORESTATE_H_
class Store;
class StoreState
{
public:
virtual void Close(Store&);
virtual void Open(Store&);
virtual void Sell(Store&);
};
#endif
The Derived class header file ConcreteStateOpened.h:
#ifndef CONCRETESTATEOPENED_H_
#define CONCRETESTATEOPENED_H_
#include "StoreState.h"
#include "Store.h"
class ConcreteStateOpened : public StoreState
{
public:
ConcreteStateOpened() {}
void Open(Store&) override;
void Close(Store&) override;
void Sell(Store&) override;
};
#endif
The Dervied class cpp file ConcreteStateOpened.cpp:
#include "ConcreteStateOpened.h"
#include <iostream>
using namespace std;
void ConcreteStateOpened::Open(Store &store)
{
cout << store.Name << " is already opened!" << endl;
}
void ConcreteStateOpened::Close(Store &store)
{
store.State = ConcreteStateOpened();
}
void ConcreteStateOpened::Sell(Store &store)
{
std::cout << "Sell Opened";
}
I don't know how to fix this. I tried removing override keywords, aswell as virtual ones. Even removing the definition etc. I just need help from pros :,)
Here are the unresolved external symbol errors:
1>ConcreteStateOpened.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Close(class Store &)" (?Close#StoreState##UAEXAAVStore###Z)
1>Data.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Close(class Store &)" (?Close#StoreState##UAEXAAVStore###Z)
1>StateStore.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Close(class Store &)" (?Close#StoreState##UAEXAAVStore###Z)
1>ConcreteStateOpened.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Open(class Store &)" (?Open#StoreState##UAEXAAVStore###Z)
1>Data.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Open(class Store &)" (?Open#StoreState##UAEXAAVStore###Z)
1>StateStore.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Open(class Store &)" (?Open#StoreState##UAEXAAVStore###Z)
1>ConcreteStateOpened.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Sell(class Store &)" (?Sell#StoreState##UAEXAAVStore###Z)
1>Data.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Sell(class Store &)" (?Sell#StoreState##UAEXAAVStore###Z)
1>StateStore.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Sell(class Store &)" (?Sell#StoreState##UAEXAAVStore###Z)
1>D:\Local-Git-Repos\DesignPatterns\StateC++\StateStore\Debug\StateStore.exe : fatal error LNK1120: 3 unresolved externals

You didn't make the methods in the abstract base pure virtual.
Also you should add : public virtual destructor, protected default constructor and remove copy/move/assignment constructors
#ifndef STORESTATE_H_
#define STORESTATE_H_
class Store;
class StoreState
{
public:
virtual ~StoreState() = default;
StoreState(const StoreState&) = delete;
StoreState(StoreState&&) = delete;
StoreState& operator=(const StoreState&) = delete;
virtual void Close(Store&) = 0;
virtual void Open(Store&) = 0;
virtual void Sell(Store&) = 0;
protected:
StoreState() = default; // prevent accidental creation
};
#endif

Your StoreState isn't actually abstract. You have declared Close, Open, Sell as actual virtual functions with definitions. To declare a virtual function with no definition in that class, use the "pure virtual" syntax = 0.
Also, it's best practice for a polymorphic class type to have a virtual destructor. And per the Rule Of Five, when you declare a destructor, be sure to think about the copy/move constructor and copy/move assignment. For an interface class, it's often best to just make it uncopyable and unassignable.
class StoreState
{
public:
StoreState() = default;
StoreState(const StoreState&) = delete;
StoreState& operator=(const StoreState&) = delete;
virtual ~StoreState() = default;
virtual void Close(Store&) = 0;
virtual void Open(Store&) = 0;
virtual void Sell(Store&) = 0;
};

For starters there is no abstract class in the presented code by you because the class StoreState does not contain pure virtual functions.
From the C++ 20 Standard (11.7.3 Abstract classes)
2 A virtual function is specified as a pure virtual function by using
a pure-specifier (11.4) in the function declaration in the class
definition. [Note: Such a function might be inherited: see below. —
end note] A class is an abstract class if it has at least one pure
virtual function. [Note: An abstract class can be used only as a
base class of some other class; no objects of an abstract class can be
created except as subobjects of a class derived from it (6.2, 11.4). —
end note] A pure virtual function need be defined only if called with,
or as if with (11.4.6), the qualified-id syntax
You need either to provide definitions of the virtual functions declared in the class StoreState or to make them pure virtual functions like for example
class StoreState
{
public:
virtual void Close(Store&) = 0;
virtual void Open(Store&) = 0;
virtual void Sell(Store&) = 0;
};
Even if a function is declared as a pure virtual function nevertheless you may provide its definition (outside the class definition where it is declared as a pure virtual function) if it is required.
Pay attention to that when you have polymorphic classes then you should declare the destructor also as virtual. For example
class StoreState
{
public:
virtual ~StoreState() = default;
virtual void Close(Store&) = 0;
virtual void Open(Store&) = 0;
virtual void Sell(Store&) = 0;
};

You may need to add virtual to the concrete class methods
#ifndef CONCRETESTATEOPENED_H_
#define CONCRETESTATEOPENED_H_
#include "StoreState.h"
#include "Store.h"
class ConcreteStateOpened : public StoreState
{
public:
ConcreteStateOpened() {}
virtual void Open(Store&) override;
virtual void Close(Store&) override;
virtual void Sell(Store&) override;
};
#endif

Related

linker errors: DLL and inheritance

I am looking for the source of the error since a few hours without success. My project consists of two sub projects. The first one is a dll and the second one is an application (exe).
I simplified my original code, which is part of the dll:
#ifndef blub_base
#define blub_base
#include "SomeInterface.hpp"
#include "Object.hpp"
#include <map>
namespace a
{
namespace b
{
class __declspec(dllexport) CBase : public CSomeInterface
{
protected:
CBase() {}
public:
CBase(SomeDifferentObject* f_object_p) { /* concrete implementation in cpp */ }
~CBase() { /* concrete implementation in cpp */ }
bool initialize() { /* concrete implementation in cpp */ }
bool shutdown() { /* concrete implementation in cpp */ }
void foo() { /* concrete implementation in cpp */ }
virtual void blubblub(Object* f_object_p) { /* concrete implementation in cpp */ }
protected:
bool blub1(Object* f_object_p, std::map<uint32_t, Object*>& f_something_rmap) const { /* concrete implementation in cpp */ }
bool blub2(Object* f_object_p, std::map<uint32_t, Object*>& f_something_rmap) const { /* concrete implementation in cpp */ }
void blub3(Object* f_object_p) const { /* concrete implementation in cpp */ }
};
}
}
#endif
#ifndef blub
#define blub
#include "Base.hpp"
namespace a
{
namespace b
{
class __declspec(dllexport) CChild : public CBase
{
private:
CChild() {}
public:
CChild(SomeDifferentObject* f_object_p) { /* concrete implementation in cpp */ }
/// deconstructor
~CChild() { /* concrete implementation in cpp */ }
void blubblub(Object* f_object_p) override { /* concrete implementation in cpp */ }
protected:
bool blub1(Object* f_object_p, std::map<uint32_t, Object*>& f_something_rmap) const override { /* concrete implementation in cpp */ }
bool blub2(Object* f_object_p, std::map<uint32_t, Object*>& f_something_rmap) const override { /* concrete implementation in cpp */ }
void blub3(Object* f_object_p) const override { /* concrete implementation in cpp */ }
};
}
}
#endif
If I am trying to instantiate a CChild object in my application I get linker errors for all functions of the CChild class:
Error 75 error LNK2001: unresolved external symbol "public: virtual void __thiscall a::b::CChild::blubblub(class a::b::Object *)" (?blubblub#CChild#b#a##UAEXPAVObject#23##Z) application.obj Application
Error 74 error LNK2019: unresolved external symbol "public: virtual __thiscall a::b::CChild::~CChild(void)" (??1CChild#b#a##UAE#XZ) referenced in function "public: virtual void * __thiscall a::b::CChild::`vector deleting destructor'(unsigned int)" (??_ECChild#b#a##UAEPAXI#Z) Application.obj Application
Error 73 error LNK2019: unresolved external symbol "public: __thiscall a::b::CChild::CChild(class a::b::SomeDifferentObject *)" (??0CChild#b#a##QAE#PAVSomeDifferentObject#12##Z) referenced in function _main Application.obj Application
Error 77 error LNK2001: unresolved external symbol "protected: virtual bool __thiscall a::b::CChild::blub1(class Object *,class std::map,class std::allocator > > &)const " (?blub1#CChild#b#a##MBE_NPAVObject#23#AAV?$map#KIU?$less#K#std##V?$allocator#U?$pair#$$CBKI#std###2##std###Z) Application.obj Application
Error 76 error LNK2001: unresolved external symbol "protected: virtual bool __thiscall a::b::CChild::blub2(class Object *,class std::map,class std::allocator > > &)const " (?blub2#CChild#b#a##MBE_NPAVObject#23#AAV?$map#KIU?$less#K#std##V?$allocator#U?$pair#$$CBKI#std###2##std###Z) Application.obj Application
Error 78 error LNK2001: unresolved external symbol "protected: virtual void __thiscall a::b::CChild::blub3(class a::b::Object *)const " (?blub3#CChild#b#a##MBEXPAVObject#23##Z) Application.obj Application
I am using Visual Studio and all cpp files are in the project (checked many times). Each function is implemented e.g.
CChild::CChild(SomeDifferentObject* f_object_p) : CBase(f_object_p)
{
}
It seems that the relevant cpp files are not found?!
Thank you very much for your help!
Kind regards,
Bobby
It is not working because classes are always exported. They need to be exported by dll project and imported by projects that use that dll.
To fix this, add header file, for example ab_dll.h and there:
#ifdef AB_DLL_EXPORT
#define AB_DLL_API __declspec(dllexport)
#else
#define AB_DLL_API __declspec(dllimport)
#endif
Then use that macro in your classes:
class AB_DLL_API CBase : public CSomeInterface
{
//...
};
class AB_DLL_API CChild : public CBase
{
//...
};
Also in your VS dll project add AB_DLL_EXPORT in PreprocessorDefinitions so that the classes are exported. This works that way that if AB_DLL_EXPORT is defined in the project then classes will be exported, otherwise will be imported.

How should I add the functionality of another class's method to my current class?

I'm creating a mod for Half Life 2 and want to add a method from physcannon.cpp to the crossbow.cpp. I first tried making the physcannon class a friend class of the crossbow class, including the physcannon.cpp in the crossbow cpp then calling one of physcannon's methods inside one of crossbow's methods but get the below errors (this is just a few of a the many similar errors). Part of Crossbow's class looks like this and I think the errors were caused by the includes of both cpp files overlapping somehow. Is there a different C++ technique I could use here to call the Force() method of the physcannon class in the crossbow class?
class CWeaponCrossbow : public CBaseHLCombatWeapon
{
DECLARE_CLASS( CWeaponCrossbow, CBaseHLCombatWeapon );
public:
CWeaponCrossbow( void );
virtual void Precache( void );
virtual void PrimaryAttack( void );
virtual void SecondaryAttack( void );
virtual void Force( void ) { CWeaponPhysCannon A; A.Force(); };
virtual bool Deploy( void );
virtual void Drop( const Vector &vecVelocity );
virtual bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
virtual bool Reload( void );
virtual void ItemPostFrame( void );
virtual void ItemBusyFrame( void );
virtual void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );
virtual bool SendWeaponAnim( int iActivity );
virtual bool IsWeaponZoomed() { return m_bInZoom; }
1>weapon_physcannon.obj : error LNK2005: "public: static struct datamap_t * __cdecl game_shadowcontrol_params_t::GetBaseMap(void)" (?GetBaseMap#game_shadowcontrol_params_t##SAPAUdatamap_t##XZ) already defined in weapon_crossbow.obj
1>weapon_physcannon.obj : error LNK2005: "private: static struct datamap_t * __cdecl CGrabController::GetBaseMap(void)" (?GetBaseMap#CGrabController##CAPAUdatamap_t##XZ) already defined in weapon_crossbow.obj
1>weapon_physcannon.obj : error LNK2005: "public: void __thiscall CGrabController::OnRestore(void)" (?OnRestore#CGrabController##QAEXXZ) already defined in weapon_crossbow.obj
1>weapon_physcannon.obj : error LNK2005: "public: virtual enum IMotionEvent::simresult_e __thiscall CGrabController::Simulate(class IPhysicsMotionController *,class IPhysicsObject *,float,class Vector &,class Vector &)" (?Simulate#CGrabController##UAE?AW4simresult_e#IMotionEvent##PAVIPhysicsMotionController##PAVIPhysicsObject##MAAVVector##2#Z) already defined in weapon_crossbow.obj
1>weapon_physcannon.obj : error LNK2005: "private: virtual struct datamap_t * __thiscall CPlayerPickupController::GetDataDescMap(void)" (?GetDataDescMap#CPlayerPickupController##EAEPAUdatamap_t##XZ) already defined in weapon_crossbow.obj
1>weapon_physcannon.obj : error LNK2005: "public: static struct datamap_t * __cdecl thrown_objects_t::GetBaseMap(void)" (?GetBaseMap#thrown_objects_t##SAPAUdatamap_t##XZ) already defined in weapon_crossbow.obj
1>weapon_physcannon.obj : error LNK2005: "public: virtual class ServerClass * __thiscall CWeaponPhysCannon::GetServerClass(void)" (?GetServerClass#CWeaponPhysCannon##UAEPAVServerClass##XZ) already defined in weapon_crossbow.obj
1>weapon_physcannon.obj : error LNK2005: "public: virtual int __thiscall CWeaponPhysCannon::YouForgotToImplementOrDeclareServerClass(void)" (?YouForgotToImplementOrDeclareServerClass#CWeaponPhysCannon##UAEHXZ) already defined in weapon_crossbow.obj
1>weapon_physcannon.obj : error LNK2005: "public: virtual struct datamap_t * __thiscall CWeaponPhysCannon::GetDataDescMap(void)" (?GetDataDescMap#CWeaponPhysCannon##UAEPAUdatamap_t##XZ) already defined in weapon_crossbow.obj
1>weapon_physcannon.obj : error LNK2005: "public: virtual void __thiscall CWeaponPhysCannon::WeaponIdle(void)" (?WeaponIdle#CWeaponPhysCannon##UAEXXZ) already defined in weapon_crossbow.obj
EDIT:
For greatwolf: CWeaponCrossbow and CWeaponPhysCannon both inherit from CbaseHLCombatWeapon and override function etc etc. I am attempting to add one of the functions in CWeaponPhysCannon to be usable in the CWeaponCrossbow class (and eventually all other weapons will also get this added method).
I like the idea of having an intermediate base class as suggested by Tristan Brindle and will be attempting that. Does the intermediate base class only need the
virtual void Force( void ) { CWeaponPhysCannon A; A.Force(); };
I am trying to implement into the crossbow or do I need to put in every placeholder function as well? (not new to polymorphism but not experienced either) Thanks!
You can't just include "physcannon.cpp" inside "crossbow.cpp". Doing so will result in duplicate definitions of things inside "physcannon.cpp", which is causing the errors you're seeing at link-time.
If what you want is to use some private functions defined inside the physcannon.cpp file, try to move them to a separate file with its own header. You can then include the header in both "physcannon.cpp" and "crossbow.cpp". Alternatively, if the functions are small, put the definitions in the header and make them inline.
If what you want is to use PhysCannon methods in your Crossbow class, then this won't work. The best thing you can do in this case is to move these methods to an intermediate base class, like
class CHLCombatWeaponWithSomePhysics : public CBaseHLCombatWeapon
{
// Define some methods that were previously in PhysCannon
};
Then change both physcannon and crossbow so they inherit from this intermediate class.

error LNK2019 unresolved external symbol virtual class

I know this question was asked several time, but i don't find how to resolve it.
I get this error when i'm trying to build my project:
error LNK2019: unresolved external symbol "public: virtual __thiscall IGameState::~IGameState(void)" (??1IGameState##UAE#XZ) in function "public: virtual __thiscall MenuState::~MenuState(void)" (??1MenuState##UAE#XZ)
Here is my code:
IGameState.h
class IGameState
{
public:
virtual ~IGameState();
virtual void update() = 0;
virtual void render() = 0;
};
MenuState.h
#include "IGameState.h"
class MenuState : public IGameState
{
public:
MenuState();
~MenuState();
void update();
void render();
};
MenuState.cpp
#include "MenuState.h"
#pragma region Constructor
MenuState::MenuState() {
}
MenuState::~MenuState() {
}
#pragma endregion
void MenuState::render() {
}
void MenuState::update() {
}
What's wrong with the destructor?
Thanks.
The error message tells you that's a link error, because you haven't implemented ~IGameState(),
Try add below code:
class IGameState
{
public:
virtual ~IGameState() {}
//^^^^ define it
virtual void update() = 0;
virtual void render() = 0;
};

Template Specialization with External Errors

When I attempted to specialize one of my template functions, Visual Studio threw me an external error, including an error for a function that was not specialized.
The three errors:
1>------ Build started: Project: Project3, Configuration: Debug Win32 ------
1>main.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall linearList<class FriendToken>::reverse(void)" (?reverse#?$linearList#VFriendToken####UAEXXZ)
1>main.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall linearList<class FriendToken>::print(void)" (?print#?$linearList#VFriendToken####UAEXXZ)
1>main.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall linearList<class FriendToken>::insertionSort(void)" (?insertionSort#?$linearList#VFriendToken####UAEXXZ)
Here is the relevant part of the code:
template<class T>
class arrayList : public linearList<T>
{
public:
//other methods
void reverse();
void print();
void insertionSort();
};
template<class T>
void arrayList<T>::reverse()
{
//method body
}
template<>
void arrayList<FriendToken>::insertionSort()
{
//method body
}
template<>
void arrayList<FriendToken>::print()
{
//method body
}
template<class T>
void arrayList<T>::insertionSort(){}
template<class T>
void arrayList<T>::print(){}
Your example shows specializations of the arrayList member functions which I assume are supposed to be overriding their virtual equivalants in linearList. The linker is saying it cant find the virtual members in the class linearList which is not included in your example.
virtual void __thiscall linearList<class FriendToken>::reverse(void)
If I add a definition of linearList like this the linker is quiet (on MSVC2010, I also added a empty FriendToken class to make things work).
template<typename T>
class linearList
{
public:
virtual void reverse() = 0; //pure virtual
virtual void print() = 0;
virtual void insertionSort() = 0;
};
If this is not your problem please post the code for linearList and I will update my answer as that is surely the source of your problem.
If needed for reference here is how I used the function reverse to test:
arrayList<FriendToken> a;
static_cast<linearList<FriendToken>&>(a).reverse();

Unresolved External (abstract class constructor/destructor)

So, I have an abstract class Panel and an implementation of it MyPanel. They look similar to this:
class Panel : public QWidget
{
public:
Panel(QWidget* parent = 0) = 0;
virtual ~Panel() = 0;
// but wait, there's more!!
};
class MyPanel : public Panel
{
public:
MyPanel(QWidget* parent = 0);
~MyPanel() {}; // nothing to do here
};
MyPanel::MyPanel(QWidget* parent) :
Panel(parent)
{
// you must construct additional pylons
}
I'm getting linker errors for the constructor/destructor from VC++
error LNK2019: unresolved external symbol "public: virtual __thiscall Panel::~Panel(void)" (??1Panel##UAE#XZ) referenced in function "public: virtual __thiscall MyPanel::~MyPanel(void)" (??1MyPanel##UAE#XZ) mypanel.obj
error LNK2019: unresolved external symbol "public: __thiscall Panel::Panel(class QWidget *)" (??0Panel##QAE#PAVQWidget###Z) referenced in function "public: __thiscall MyPanel::MyPanel(class QWidget *)" (??0MyPanel##QAE#PAVQWidget###Z) mypanel.obj
Why am I getting this linker error?
--- THE ANSWER ---
class Panel : public QWidget
{
public:
Panel(QWidget* parent = 0) : QWidget(parent) {};
virtual ~Panel() {};
// but wait, there's more!!
};
I thought I had tried this before lunch. Turns out I was wrong.
there is no such thing like virtual constructor.
You still should provide implementation of destructor.
Purely virtual destructors still need to have an implementation.
To expand on that a bit:
The destructor of a class will always be called if any instance of a subclass gets destructed, so it needs to have an implementation. (Basically the only effect of making a destructor purely virtual is that it prevents instanatiation of the class).
As for the constructor: You're making it purely virtual (which I don't see any reason for doing), but then you explicitly call it from the subclass's constructor.