I have a static method called getSingleton() in a class called Renderer, which I use as a macro like this:
Renderer.h
#define g_Renderer Renderer::getSingleton()
class Renderer {
private:
Renderer();
static Renderer renderer;
public:
Renderer getSingleton();
};
Renderer.cpp
#include "Renderer.h"
Renderer::Renderer() {}
Renderer Renderer::getSingleton() {
#ifndef CREATED_RENDERER
#define CREATED_RENDERER;
renderer = Renderer();
#endif // !CREATED_RENDERER
return renderer;
}
I access the method in main:
Main.cpp
#include "Renderer.h"
int main(){
return 0;
}
But Visual Studio gives me this error:
Main.obj : error LNK2019: unresolved external symbol "public: static class Renderer __cdecl Renderer::getSingleton(void)" (?getSingleton#Renderer##SA?AV1#XZ) referenced in function main
Why is this? Thanks in advance!
Your getRenderer() method is setup all wrong for what you are trying to do.
For one thing, it is not static.
For another, the static variable is only being declared, not defined anywhere, which is why the linker is complaining. You would need to add this line to Renderer.cpp to actually instantiate the variable:
Renderer Renderer::renderer;
Also, getRenderer() is returning a new Renderer object each time it is called, which is useless for a singleton. The #ifdef is also useless at runtime.
Try something more like this instead:
Renderer.h
#ifndef Renderer_H
#define Renderer_H
#define g_Renderer Renderer::getSingleton()
class Renderer {
private:
Renderer();
public:
static Renderer& getSingleton();
};
#endif
Renderer.cpp
#include "Renderer.h"
Renderer::Renderer() {}
Renderer& Renderer::getSingleton() {
static Renderer instance;
return instance;
}
Main.cpp
#include "Renderer.h"
int main(){
// use g_Renderer as needed...
return 0;
}
Related
i'm working on an intake assignment for a game development course but i'm stuck with an annoying error by visual studio after splitting my code into classes. The error states LNK2019 unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ) So it should be something wrong in my main function. I've looked around and the most logical reason seemt to be wrong subsystem but that's set to console application. Here's my code:
Main.cpp:
#include <Box2D/Box2D.h>
#include <SFML/Graphics.hpp>
#include "Game.hpp"
int main() {
Game game; //Sets up the game
game.populateWorld();
while (game.window.isOpen()) {
game.checkEvents();
game.drawBodies();
game.m_Player->movePlayer();
}
return 0;
}
Game.hpp:
#ifndef Game_hpp
#define Game_hpp
#include <SFML/Graphics.hpp>
#include "World.hpp"
#include "Player.hpp"
class Game {
public:
Game();
void checkEvents();
void drawBodies();//Displays the bodies and keeps the view centered
//Public data members to be used by other classes
sf::Texture backGroundTexture;
sf::Texture playerTex;
sf::Texture platformTex;//Doesn't have a sprite declared since multiple copy's will be made
sf::Sprite backGround;
sf::Sprite player;
sf::View view;
sf::RenderWindow window;
const float m_Scale;//Number of pixels per meter
Player* m_Player = NULL;
World* m_World = NULL;
void populateWorld();
private:
void loadResources();//Loads resources and applies them where needed
};
#endif // !Game_hpp
World.hpp:
#ifndef World_hpp
#define World_hpp
#include <Box2D/Box2D.h>
class World {
public:
//Public member functions
World(const float scale);
~World();
void step();
b2Body* spawnPlayer(float x, float y);
//Public data members
b2World* world = NULL; //Points to the entire world! Handle with care ;)
void createPlatform(b2Vec2 point);
private:
//Private data members
b2Vec2 gravity;
const float m_Scale;
//Declaring step values
float32 m_TimeStep;
int32 m_VelocityIterators;
int32 m_PositionIterators;
};
#endif // !World_hpp
Player.hpp:
#ifndef Player_hpp
#define Player_hpp
#include <Box2D/Box2D.h>
#include "World.hpp"
class Player{
public:
Player(World* world, const float scale, float x, float y);
void movePlayer();
b2Body* m_PlayerBody;//A pointer to the player Character's body needed for the movement
private:
World* m_World;
const float m_Scale;
};
#endif // !Player_hpp
Hope anyone can point me in the right direction with what's going wrong :)
Guess i was ignorant... There was a warning about the main.cpp using line endings for Mac Os X since i work on an iMac i didn't care. But when i fixed this in Notepad++ EDIT -> EOL Conversion -> Windows Format, it worked like a sharm! My bad i'm afraid ^^
I solved my problem by the following:
1) closing the project and restarting the PC
2) Creating a new project and following this thread because I was doing GUI
http://www.bogotobogo.com/cplusplus/application_visual_studio_2013.php
I have an DLL in which I have added a second class which has only static members, but when I try to build this I got linker error:
Error 14 error LNK2001: unresolved external symbol "__declspec(dllimport) private: static double BubblyCore::BubblyTime::delta" (__imp_?delta#BubblyTime#BubblyCore##0NA) D:\Projekty\bubbly-engine\BCore\BCore.obj BCore
And same for second member.
Here is my header:
#ifdef BCOREDLL_EXPORTS
#define BCOREDLL_API __declspec(dllexport)
#else
#define BCOREDLL_API __declspec(dllimport)
#endif
#include <..\BDisplay.h>
#include <ctime>
#include <chrono>
typedef std::chrono::time_point<std::chrono::system_clock, std::chrono::system_clock::duration> BChronoTime;
namespace BubblyCore
{
// This class is exported from the BCOREDll.dll
class BCOREDLL_API MainBubble
{
public:
private:
BDisplay* pbDisplay;
bool isRunning;
public:
MainBubble(BDisplay* pbDisplay);
void Start();
void Stop();
private:
void Run();
void Render();
void CleanUp();
};
class BCOREDLL_API BubblyTime
{
public:
static BChronoTime bStartTime;
private:
static double delta;
public:
static long getTime();
static double getDelta();
static void setDelta(double sDelta);
};
}
I am talking specific about BubblyTime. The first one is Ok so far.
Inside one of your .cpp files, add the following lines :
double BubblyCore::BubblyTime::delta = 0.0;
Declaring static variables in a header file won't be sufficient. You need to declare their real instances in some .cpp files.
Hope some one could help me with this very trivial error which I have not idea how to proceed :)
Here's the header file:
#ifndef __InputHandler__
#define __InputHandler__
#include "SDL.h"
#include <SDL_image.h>
#include <vector>
#include <iostream>
enum mouse_buttons {
LEFT = 0,
MIDDLE = 1,
RIGHT = 2,
};
class InputHandler {
public:
bool getMouseButtonState(int buttonNumber) {
return m_mouseButtonStates[buttonNumber];
}
std::vector<bool> m_mouseButtonStates;
static InputHandler* Instance() {
if (s_pInstance == 0) {
s_pInstance = new InputHandler();
}
return s_pInstance;
}
void update();
void clean();
private:
InputHandler();
~InputHandler() {}
static InputHandler* s_pInstance;
};
#endif
And I call the InputHandler::Instance() function in another class definition Player.cpp
#include "InputHandler.h"
void Player::handleInput() {
if (InputHandler::Instance()->getMouseButtonState(LEFT)) {
m_velocity.setX(1);
}
}
Here's the error that I get:
Player.obj : error LNK2001: unresolved external symbol
"private: static class InputHandler * InputHandler::s_pInstance"
I honestly don't know what's going on and what the error is pointing to. REALLY REALLY appreciate your wisdom :)))
"I honestly don't know what's going on and what the error is pointing to. "
The linker error message pretty much tells you what's missing.
The current problem you have, is you're missing a definition for the static InputHandler* s_pInstance; member in a translation unit. It should look like this:
InputHandler* InputHandler::s_pInstance = 0;
Though your approach to the singleton pattern has some flaws and deficiencies (especially regarding thread safety). You should simplify your singleton pattern like this:
static InputHandler& Instance() {
static InputHandler theInputHandler;
return theInputHandler;
}
or if you insist using a a pointer
static InputHandler* Instance() {
static InputHandler theInputHandler;
return &theInputHandler;
}
This is commonly known as 'Scott Meyer's Singleton idiom', here's some more information about the original reasonings;
C++ and the Perils of Double-Checked Locking
IClass (My interface):
#ifndef _ICLASS_H
#define _ICLASS_H
#include <sstream>
namespace Test
{
class __declspec(dllexport) IClass
{
public:
virtual ~IClass() {}
virtual bool Init(const std::string &path) = 0;
};
}
#endif
Class.h
#ifndef _CLASS_H
#define _CLASS_H
#include "IClass.h"
#include <memory>
#include <sstream>
#include <stdio.h>
namespace Test
{
class Class: public IClass
{
public:
Class();
~Class();
bool Init(const std::string &path);
};
}
#endif
Class.cpp
#include "Class.h"
namespace Test
{
Class::Class()
{
}
bool Class::Init(const std::string &path)
{
try
{
// do stuff
return true;
}
catch(std::exception &exp)
{
return false;
}
}
}
main (in exe, dll linked implicitly)
#include "IClass.h"
using namespace Test;
int main(int argc, char* argv[])
{
std::shared_ptr<IClass> test = std::make_shared<Class>(); // error: unreferenced Class
test->Init(std::string("C:\\Temp"));
}
At the moment Class is not declared
-> if I include Class.h to main following error occurs: LNK2019: unresolved external symbol: add class __declspec(dllexport) Class : public IClass resolve this linker issue, but is it ok to do it this way?
-> I also can't do this: std::shared_ptr<IClass> test = std::make_shared<IClass>();
(because it's not allowed to create an object of abstract class)
How can I solve this issue and is this best practise?
If you want your EXE to allocate a new "Class" object, the EXE code has to know the Class type. If you want to keep the Class type unknown from the EXE, one solution may be to export from your DLL a factory function, which will construct a Class object and return it as an IClass pointer.
See How to implement the factory pattern in C++ correctly
My code is stored in a main.cpp file which contains the void main() function, and a class MyClass which I now want to split to another file. IDE is Microsoft Visual Studio 2008 Professional.
myclass.h
#include <tchar.h>
class MyClass {
public:
static bool MyFunction (TCHAR* someStringArgument);
};
myclass.cpp
#include <tchar.h>
class MyClass {
private:
static bool someProperty;
static void doSomeOneTimeCode () {
if (!someProperty) {
/* do something */
someProperty = true;
}
}
public:
static bool MyFunction (TCHAR* someStringArgument) {
doSomeOneTimeCode();
/* do something */
return true;
}
};
bool MyClass::someProperty = false;
main.cpp
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include "myclass.h"
void main () {
if (MyClass::MyFunction(TEXT("myString"))) {
_tprintf(TEXT("Yay\n"));
}
}
However, when I try to run it, I get two linker errors.
LNK2019: unresolved external symbol ... (mentions MyClass::MyFunction)
LNK1120: 1 unresolved externals
What can I do to prevent these linker errors?
You declared two classes here. One of them is in myclass.h and the other is in myclass.cpp. Try the following instead:
myclass.h
#ifndef myclass_h_included
#define myclass_h_included
#include <tchar.h>
class MyClass {
private:
static bool someProperty;
static void doSomeOneTimeCode ();
public:
static bool MyFunction (TCHAR* someStringArgument);
};
#endif //!myclass_h_included
myclass.cpp
#include "myclass.h"
/*static*/ bool MyClass::someProperty = false;
void
MyClass::doSomeOneTimeCode() {
//...
}
bool
MyClass::MyFunction(TCHAR* someStringArgument) {
//...
}
Your main.cpp can stay the same. I would pay attention to UncleBens reply as well. One time initialization code should be hidden if at all possible.
Yo can't split a class definition in parts. It must be defined as a whole in one place. If you want to just have some methods of the class defined create a interface class that the MyClass class will later inherit. You should put the class' definition in a header file (myclass.h) and it's implementation in a cpp file (myclass.cpp). That way you can include the "myclass.h" in your main cpp file and use the class in your main function (which should be int main() or int main( int argc, char *argv[] )).
Strange that you didn't get a compiler error, as you are redefining MyClass.
Definitions (implementations) go into the cpp, and they are defined like this:
#include "myclass.h"
//helper functions, particularly if static, don't need to be in the class
//unnamed namespace means this stuff is available only for this source file
namespace
{
bool someProperty;
void doSomeOneTimeCode () {
if (!someProperty) {
/* do something */
someProperty = true;
}
}
}
bool MyClass::MyFunction (TCHAR* someStringArgument) {
doSomeOneTimeCode();
/* do something */
return true;
}