I have the following Files in C++:
Object.h:
class Object{
public:
Object(void);
~Object(void);
GLfloat getLeft();
GLfloat getRight();
GLfloat getBottom();
GLfloat getTop();
};
Player.h:
class Player : public Object{
public:
Player(void);
~Player(void);
GLfloat getLeft();
GLfloat getRight();
GLfloat getBottom();
GLfloat getTop();
};
Platform.h:
class Platform : public Object{
public:
Platform(void);
~Platform(void);
GLfloat getLeft();
GLfloat getRight();
GLfloat getBottom();
GLfloat getTop();
};
Pillar.h:
class Pillar : public Object{
public:
Pillar(void);
~Pillar(void);
GLfloat getLeft();
GLfloat getRight();
GLfloat getBottom();
GLfloat getTop();
};
Collision.h:
#include "Player.h"
#include "Platform.h"
#include "Pillar.h"
class Collision
{
public:
Collision(void);
~Collision(void);
bool CollisionDetect(Object* obj1, Object* obj2);
};
Collision.cpp:
bool Collision::CollisionDetect(Object* obj1, Object* obj2){
return !(obj2->getLeft() > obj1->getRight()
|| obj2->getRight() < obj1->getLeft()
|| obj2->getTop() > obj1->getBottom()
|| obj2->getBottom() < obj1->getTop());
}
CollisionDetect will be comparing whether 2 different Objects have collided and to do this I need specific x and y values however, the types of object may vary depending on different circumstances, and each type of object will have different ways to find their x and y values. This means that I have had to re-define the relevant get Methods in their subclasses, but when I run this code I end up with the errors:
1>Collision.obj : error LNK2019: unresolved external symbol "public: float __thiscall Object::getLeft(void)" (?getLeft#Object##QAEMXZ) referenced in function "public: bool __thiscall Collision::CollisionDetect(class Object *,class Object *)" (?CollisionDetect#Collision##QAE_NPAVObject##0#Z)
1>Collision.obj : error LNK2019: unresolved external symbol "public: float __thiscall Object::getRight(void)" (?getRight#Object##QAEMXZ) referenced in function "public: bool __thiscall Collision::CollisionDetect(class Object *,class Object *)" (?CollisionDetect#Collision##QAE_NPAVObject##0#Z)
1>Collision.obj : error LNK2019: unresolved external symbol "public: float __thiscall Object::getBottom(void)" (?getBottom#Object##QAEMXZ) referenced in function "public: bool __thiscall Collision::CollisionDetect(class Object *,class Object *)" (?CollisionDetect#Collision##QAE_NPAVObject##0#Z)
1>Collision.obj : error LNK2019: unresolved external symbol "public: float __thiscall Object::getTop(void)" (?getTop#Object##QAEMXZ) referenced in function "public: bool __thiscall Collision::CollisionDetect(class Object *,class Object *)" (?CollisionDetect#Collision##QAE_NPAVObject##0#Z)
1>C:\Users\Student\Dropbox\Work\Year 2\Graphics 1\Coursework\GraphicsCoursework\Debug\GraphicsCoursework.exe : fatal error LNK1120: 4 unresolved externals
Is it a problem with my inheritance that is causing this, or is it something else?
Exactly make the 4 functions in the object class "virtual"
Infact i would suggest make it pure virtual,
class Object{
public:
Object(void);
~Object(void);
virtual GLfloat getLeft() = 0;
virtual GLfloat getRight() = 0;
virtual GLfloat getBottom() = 0;
virtual GLfloat getTop() = 0;
};
This will force you to override those four function in the derived class, and provide a definition..
Each of your classes, Derived as well as Base need to define those 4 member functions.
Only pure virtual functions in C++ are allowed to exist without a definition.
Also, the redeclaration and definition of these 4 member functions in derived classes HIDE the functions in the Base class. From your usage it seems you want to use dynamic polymorphism through function overidding and for that you need to use the keyword virtual.
seems like you need virtual functions.
class Object{
public:
Object(void);
~Object(void);
virtual GLfloat getLeft()=0;
virtual GLfloat getRight()=0;
virtual GLfloat getBottom()=0;
virtual GLfloat getTop()=0;
};
Related
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
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is an undefined reference/unresolved external symbol error and how do I fix it?
I have a LNK error that involves a class A and its derived class B. More precisely, I have this compilation error
Error 239 error LNK2019: unresolved external symbol "public: virtual __thiscall A::~A(void)" (??1A##UAE#XZ) referenced in function "public: virtual __thiscall B::~B(void)" (??1B##UAE#XZ) D:\Products\path\file.lib(B.obj)
Error 240 error LNK2019: unresolved external symbol "public: __thiscall A::A(void)" (??A##QAE#XZ) referenced in function "public: __thiscall B::B(void)" (??B##QAE#XZ) D:\Products\path\file.lib(B.obj)
Error 241 error LNK2019: unresolved external symbol "public: void __thiscall A::function(float * *,float * *,float * *,float * *,int)" (?function#A##QAEXPAPAM000H#Z) referenced in function "public: class SomeType* __thiscall B::function_bis(void)" (?function_bis#B##QAEPAVSomeType##XZ) D:\Products\path\file.lib(B.obj)
I guess this may be related to, say, call of inherited constructor, or the non-respect of the signature in some call of function() or function_bis(). However, such mistakes i cannot find.
Do you have a hint to a possible way to solve ? Here is code for (simplified) A and B.
B.cpp
B::B(void)
{
}
B::B(Type1* d1, Type1* d2, Type1* r):A()
{
D1= d1;
D2= d2;
R= r;
}
B::~B( void )
{
}
SomeType* B::function()
{
// do things
function_bis() ;
}
B.h
class B:
public A
{
public:
B(void) ;
B(Type1* , Type1* , Type1* );
virtual ~B(void);
SomeType* function() ;
private:
Type1* D1;
Type1* D2;
Type1* R;
};
A.cpp
using namespace std ;
A::A(void){}
A::~A(void){}
void A::function_bis(float** d, float** d2, float** d3, float** d4, int n)
{}
A.h
class A
{
public:
A(void);
virtual ~A(void);
void function_bis(float** , float** , float** , float** , int );
};
Thanks!
Everything looks legit in your code.
My guess is that you actually don't compile A.cpp or somehow you don't include the resulting object file in your linking step (you miss A::A, A::~A and A::function_bis which are defined in A.cpp).
I can't figure out where my error is.
I get the message:
Error 21 error LNK2019: unresolved external symbol "public: __thiscall ParticleAnchoredSpring::ParticleAnchoredSpring(class Vector3 *,float,float)" (??0ParticleAnchoredSpring##QAE#PAVVector3##MM#Z) referenced in function "public: void __thiscall MyGameWorld::Initialize(void)" (?Initialize#MyGameWorld##QAEXXZ) C:\Users\Foo Nuts\Dropbox\GSP321_DavidJohnson\GSP321_Johnson_HM2\iLab2\MyGameWorld.obj
function declaration:
ParticleForceRegistry registry;
ParticleAnchoredSpring spring(&Vector3(10, 3, 10), 10, 10);
registry.add(WMI->getListPtr()[0], &spring);
class definition:
class ParticleAnchoredSpring : public ParticleForceGenerator
{
protected:
Vector3 *anchor;
real springConstant, restLength;
public:
ParticleAnchoredSpring(Vector3 *anchor, real springConstant, real restLength);
virtual void updateForce(Particle *particle, real time);
};
constructor declaration:
void ParticleAnchoredSpring::updateForce(Particle *particle, real time)
{
Vector3 force;
particle->getPosition();
force -= *anchor;
real magnitude = force.magnitude();
magnitude = (restLength - magnitude) * springConstant ;
magnitude *= springConstant;
force.normalize();
force *= -magnitude;
particle->addForce(force);
}
You haven't implemented the constructor. You only declared it. Add:
ParticleAnchoredSpring::ParticleAnchoredSpring(Vector3 *_anchor, real _springConstant, real _restLength)
: anchor(_anchor), springConstant(_springConstant), restLength(_restLength)
{
}
to your implementation file.
I'll assume real is defined as float.
#include <iostream>
using namespace std;
class A {
public:
void function( int num);
bool function1()const;
virtual bool function2() const=0;
};
class B:public A {
public :
bool function2()const;
};
int _tmain(int argc, _TCHAR* argv[])
{
void (A::* p)(int)= &A::function; //不是地址,而是一个指向成员函数的指针
// Edit: Google translation of the above comment is
// "Not address, but a pointer to a member function pointer"
bool (A::* p1)()const =&A::function1; // 指向成员函数的指针可以指向一个常量成员函数
// Edit: Google translation of the above comment is
// "Point to a member function pointer can point to a const member function"
B b;
A *a=&b;
(a->*p1)();
(b.*p1)();
return 0;
}
but when I link it:
1>c.obj : error LNK2019: unresolved external symbol "public: bool __thiscall A::function1(void)const " (?function1#A##QBE_NXZ) referenced in function _wmain
1>c.obj : error LNK2019: unresolved external symbol "public: void __thiscall A::function(int)" (?function#A##QAEXH#Z) referenced in function _wmain
1>c.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall B::function2(void)const " (?function2#B##UBE_NXZ)
can you tell me why?
You haven't implemented A::function(), A::function1(), or B::function2(). You need to do that.
A::function1, A::function and B::function2 are all declared, but never defined. You can't get a pointer to the function if it is not defined, where would it point?