How would I handle this linker error? - mfc

I'm building a mfc application that will enable the user to draw graphical objects (something like ms paint). But for some reason I'm getting the following linker error:
CElement.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CElement::Draw(class CDC *)" (?Draw#CElement##UAEXPAVCDC###Z).
I know it's something related to the virtual draw function in the CPolygon class. But what hat exactly is causing it?
//CElement.h
class CElement : public CObject
{
public:
virtual ~CElement();
virtual void Draw(CDC* pDC);
};
NOTE: CElement will act as a base class for all other classes like CPolyline and CRectangle. The Draw function is virtual- an example of polymorphism, CElement's Draw(CDC* pDC) will be overridden by the Draw() functions of the derived classes
class CPolygon : public CElement
{
public:
CPolygon(CPoint mFirstPoint,CPoint mSecondPoint);
~CPolygon(void);
virtual void Draw(CDC* pDC);
---------------------------------------------------------------------------------------
//CElement.cpp
#include "CElement.h"
//constructors for the class
void CPolygon::Draw(CDC* pDC)
{
pDC->MoveTo(mStartPoint);
pDC->LineTo(mEndPoint);
}

Well as the error message says you have not defined a body for the function
virtual void Draw(CDC* pDC);
either define it or make the class abstract i.e. derived classes must implement it.
virtual void Draw(CDC* pDC) { }
or
virtual void Draw(CDC* pDC) = 0;

Related

Unresolved External Symbol how to fix it? abstract class

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

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;
};

MFC dlg class link errors for MyClass::GetMessageMap() and MyClass::GetRuntimeClass (MSVC 2008)

I copied an existing header for a dlg box class (created with the dlg class wizard/mfc wizard). All seemed to go fine until I added the cpp file to the project. Now i get odd link errors for some mfc magic methods:
error LNK2001: unresolved external
symbol "public: virtual struct
CRuntimeClass * __thiscall
DlgGapWindow::GetRuntimeClass(void)const
"
(?GetRuntimeClass#DlgGapWindow##UBEPAUCRuntimeClass##XZ)
error LNK2001: unresolved external
symbol "protected: virtual struct
AFX_MSGMAP const * __thiscall
DlgGapWindow::GetMessageMap(void)const
"
(?GetMessageMap#DlgGapWindow##MBEPBUAFX_MSGMAP##XZ)
Why would this be?
Here is the relevant code in the header
class DlgGapWindow : public CDialog
{
DECLARE_DYNAMIC(DlgGapWindow)
public:
DlgGapWindow(CWnd* pParent = NULL);
virtual ~DlgGapWindow();
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual BOOL OnInitDialog();
enum { IDD = IDD_DIALOG_GAP_VIEW };// Dialog Data
GapViewer m_chart;
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnSizing(UINT fwSide, LPRECT pRect) ;
afx_msg void OnTimer(ONTIMER_TYPE nIDEvent);
afx_msg void OnDestroy();
afx_msg void OnClose();
afx_msg void OnActivate(UINT,CWnd *,BOOL);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP()
};
I don't see anything from the class I modeled it after that seems to be missing. I have not found anything useful with google or other searches to indicate why these magic mfc things are missing. My other classes don't explicitly define them and they don't have errors.
The RC file does have a corresponding dlg definition.
EDIT:
Thanks for the DECLARE_DYNAMIC help - now I do not have the GetRuntimClass() error - just the GetMessagemap() error.
You used DECLARE_DYNAMIC but forgot IMPLEMENT_DYNAMIC.
Oops
I forgot BEGIN_MESSAGE_MAP.
Thanks for the help

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.