C++: static member functions and variables- redefinition of static variable? - c++

I was trying to incorporate the Singleton design pattern into my code, but I started getting a weird error:
main.obj : error LNK2005: "private: static class gameState * gameState::state" (?state#gameState##0PAV1#A) already defined in gameState.obj
If you're not familiar with the singleton pattern, it is basically used to enforce only 1 instance of a certain object in the entire program.
Here is the relevant code:
gameState.h:
class gameState
{
public:
static gameState* Instance() {return state;}
.
.
.
private:
gameState();
static gameState* state;
};
gameState* gameState::state = new gameState();
and right now I'm just using the instance of that object in the main.cpp file:
gameState *currState = gameState::Instance();
.
.
.
for_each(currState->getHumanPieces().begin(),currState->getHumanPieces().end(), drawPieces);
It would seem I am trying to redefine gameState::state, but can't figure out why... help anyone?
that solved that, but one error still remains, which I didn't actually post before as I thought it was just part of the other one:
error LNK2019: unresolved external symbol "private: __thiscall gameState::gameState(void)" (??0gameState##AAE#XZ) referenced in function "void __cdecl `dynamic initializer for 'private: static class gameState * gameState::state''(void)" (??__E?state#gameState##0PAV1#A##YAXXZ)
any good tip on how to fix that one as well?
Thanks both of you, its fixed :D

You need to put the definition of the static gameState* into exactly one source file, i.e. this line:
gameState* gameState::state = new gameState();
If you put it in a header which is included by multiple source files, each has a definition of gameState::state which leads to errors at link-time.
For the follow-up problem, use Vadakkumpadaths advice: you need to provide a definition for gameStates constructor, not only a declaration.

Add definition for your constructor to fix second linker error.
private:
gameState()
{
}

Use a header guard macro for the redefinition problem, and explicitly define your private constructor.

Related

Forward-declare struct which only has definition in a library cpp

I'm using the bullet 3 physics library, which has the following struct definition inside one of the cpps:
struct btSingleContactCallback : public btBroadphaseAabbCallback
{
btCollisionObject* m_collisionObject;
btCollisionWorld* m_world;
btCollisionWorld::ContactResultCallback& m_resultCallback;
btSingleContactCallback(btCollisionObject* collisionObject, btCollisionWorld* world,btCollisionWorld::ContactResultCallback& resultCallback)
:m_collisionObject(collisionObject),
m_world(world),
m_resultCallback(resultCallback)
{
}
virtual bool process(const btBroadphaseProxy* proxy)
{
btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
if (collisionObject == m_collisionObject)
return true;
//only perform raycast if filterMask matches
if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
{
btCollisionObjectWrapper ob0(0,m_collisionObject->getCollisionShape(),m_collisionObject,m_collisionObject->getWorldTransform(),-1,-1);
btCollisionObjectWrapper ob1(0,collisionObject->getCollisionShape(),collisionObject,collisionObject->getWorldTransform(),-1,-1);
btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(&ob0,&ob1);
if (algorithm)
{
btBridgedManifoldResult contactPointResult(&ob0,&ob1, m_resultCallback);
//discrete collision detection query
algorithm->processCollision(&ob0,&ob1, m_world->getDispatchInfo(),&contactPointResult);
algorithm->~btCollisionAlgorithm();
m_world->getDispatcher()->freeCollisionAlgorithm(algorithm);
}
}
return true;
}
};
The problem is, the struct is never declared in any of the headers, I need to be able to create an object of this type however. The bullet libraries are statically linked, so I figured I should just be able to declare it myself in my main program as such:
struct btSingleContactCallback
: public btBroadphaseAabbCallback
{
btCollisionObject *m_collisionObject;
btCollisionWorld *m_world;
btCollisionWorld::ContactResultCallback &m_resultCallback;
btSingleContactCallback(btCollisionObject *collisionObject,btCollisionWorld *world,btCollisionWorld::ContactResultCallback &resultCallback);
virtual bool process(const btBroadphaseProxy *proxy);
};
This actually works fine, as long as I'm compiling in debug mode. However, when trying to compile in release mode, I'm getting an unresolved symbol error:
physenvironment.obj : error LNK2001: unresolved external symbol "public: __cdecl btSingleContactCallback::btSingleContactCallback(class btCollisionObject *,class btCollisionWorld *,struct btCollisionWorld::ContactResultCallback &)" (??0btSingleContactCallback##QEAA#PEAVbtCollisionObject##PEAVbtCollisionWorld##AEAUContactResultCallback#2##Z)
Could this have anything to do with c++'s name mangling? Is there a way to avoid it, without having to start making modifications in the library itself?
From a five minute look at the library code, you actually should use ContactResultCallback which is public, letting the implementation of btCollisionWorld::contactTest create and use the private btSingleContactCallback for you.
You did not implement the constructor.

Unresolved external symbol when using static

I am new to c++. I started now playing with classes and I am having a noob problem with statics.
class Test
{
public:
Test(){};
~Test(){};
static void test();
static Helper* helper;
};
void Test::test()
{
Object obj = Test::helper->getObject();
//...
}
When I try to compile it gives the error:
main.obj : error LNK2001: unresolved external symbol "public: static class Helper* Test::helper" (?helper#Test##2PAVHelper##A)
What is wrong with my code?
The first answer is correct. The reason behind this is that you need to allocate memory for static objects outside the class definition. If you define the the class in a header file, and include it in several cpp files, the compiler doesn't know where and how you want to create the object that 'helper' points to.
you need to define Test::helper. Write something like this outside the class:
Helper* Test::helper = new Helper;

Unresolved external symbol on non-inline function body

These type of errors are well discussed on SO and many other places, yet, I couldnt find a solution to my particular case.
Basically, I have made a static library project in my solution to seperate some functionality, and reference it in my current project. When I try to call a function from the library, i got this notorious linker error. I think there are no problems in setting up the project (references, dependencies etc.) .
First, I will give some minimal example of what I am working on ( there are some third party classes )
//FileReader.h
class IBKFileReader{
public:
virtual ~IBKFileReader() {} ;
virtual void readFile(std::string fileName, pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloud ) = 0 ;
};
class XYZFileReader : public IBKFileReader
{
public:
virtual void readFile(std::string fileName, pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloud )
{
}
And in my code, I call readFile function on a IBKFileReader object polymorphically.
And, this part is ok, without any errors, it compiles, links and runs.
However, when I move the body of the readFile function to a .cpp file and implement it there
(with the same signature hopefully, i copy pasted) , I got the unresolved external symbol error. This is the header of the function in .cpp file.
void XYZFileReader::readFile(std::string fileName, pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloud )
It seems that implementing the function body inline in the header file, and implementing in some seperate file makes a difference.
What do you think of this issue? Has anybody experienced something similar to this? I hope I am not missing out something obvious.
EDIT:
This is the error log i get:
1>main.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl XYZFileReader::readFile(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class boost::shared_ptr<class pcl::PointCloud<struct pcl::PointXYZ> >)" (?readFile#XYZFileReader##UEAAXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##V?$shared_ptr#V?$PointCloud#UPointXYZ#pcl###pcl###boost###Z)
EDIT:
I may have caused some misunderstanding.
FileReader.h and FileReader.cpp is in static library project. I didnt do more than just implementing the function in the cpp file, definitions and such are still there.
In the same solution, in another project I reference to this project.
I am not getting the linker error when compiling the static lib, but when I am using it.
Sorry for my bad English.
A member function that is defined inside its class member list is called an inline member function. Try moving the member definition out of the class definition.
class XYZFileReader : public IBKFileReader
{
public:
virtual void readFile(std::string fileName,
pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloud);
};
void XYZFileReader::readFile(std::string fileName,
pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloud) {}

Linker can't find function definitions, LNK2001 unresolved external symbol

Here is my simple setup: (i've hidden lots of unneeded information)
//AutoFocusTest.h
#include "camAVTEx.h"
class CAutoFocusTestApp : public CWinApp
{
protected:
camera_t* mCamera;
public:
virtual BOOL InitInstance();
};
//camAVTEx.h
class camera_avtcam_ex_t : public camera_t
{
public:
camera_avtcam_ex_t();
virtual ~camera_avtcam_ex_t();
//member variables
//member function declarations
}
//camAVTEx.cpp
#include "camAVTEx.h"
camera_avtcam_ex_t::camera_avtcam_ex_t()
{
//stuff
}
camera_avtcam_ex_t::~camera_avtcam_ex_t()
{
//stuff
}
//the rest are defined here in my program
//AutoFocusTest.cpp
#include AutoFocusTest.h
BOOL CAutoFocusTestApp::InitInstance()
{
mCamera = new camera_avtcam_ex_t();
}
This setup produces the error:
3>AutoFocusTest.obj : error LNK2001: unresolved external symbol
"public: __cdecl camera_avtcam_ex_t::camera_avtcam_ex_t(void)"
(??0camera_avtcam_ex_t##QEAA#XZ)
From everything I've read on this relatively common problem, I have not linked something causing my camera_avtcam_ex_t function definitions to not be found. However, I can't figure out what I could have missed. I have added all of the include directories and library directories, as well as added the library files to the additional dependencies section.
Can anyone spot anything that I might be missing?
Assuming you have defined the constructor for your camera_avtcam_ex_t, it's declared as private, you can't instantiate it.

Static members and LNK error in C++

I have a class that has a static member, which I want to use in the class constructor, but the code doesn't compile, and I'm left with these errors:
fatal error LNK1120: 1 unresolved externals
error LNK2001: unresolved external symbol "protected: static class Collection A::collection"
Any help will be appreciated.
Thanks.
a.h:
class A
{
protected:
static Collection<A*> collection;
};
a.cpp:
A::A() {
A::collection.push_back(this);
}
You need to add
Collection<A*> A::collection;
to your a.cpp file.
In your .cpp you need to add:
Collection<A*> A::collection;
The .h only declared that there would be a copy somewhere. You need to provide that copy in the .cpp.
alternatively, if you don't want to put that line in a cpp file, you can use a static method which returns a reference to a static instance... i.e.
class A
{
public:
static Collection<A*>& collection()
{
static Collection<A*> singleInstance;
return singleInstance;
}
};