error LNK2019: unresolved external symbol "public: void __thiscall Button::ButtonInit" [duplicate] - c++

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
I've been going through a C++/SFML tutorial (http://www.gamefromscratch.com/page/Game-From-Scratch-CPP-Edition.aspx) and, having reached the end, started altering the code to try out various things and get more comfortable both with C++ and SFML.
For the menu screen, I decided to create an object for buttons. To this end I created Button.cpp and Button.h, then linked to Button.h in the MainMenu.h file. I added Button button_play as a public member of class MainMenu, however when I call a Button function (for example: button_play.ButtonInit("new-game");), I receive the error: error LNK2019: unresolved external symbol "public: void __thiscall Button::ButtonInit(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?ButtonInit#Button##QAEXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) referenced in function "public: enum MainMenu::MenuResult __thiscall MainMenu::Show(class sf::RenderWindow &)" (?Show#MainMenu##QAE?AW4MenuResult#1#AAVRenderWindow#sf###Z)
I've done a lot of searching around this, and most of the answers I've found revolve around not implementing class member functions correctly, however as far as I can tell I am doing it correctly. I am, however, very new to C++, so it's possible that I'm just missing something.
Here's my code:
MainMenu.h
#pragma once
#include "SFML\Window.hpp"
#include "SFML\Graphics.hpp"
#include "GameObjectManager.h"
#include "Button.h"
#include <list>
class MainMenu
{
public:
MainMenu(){};
~MainMenu() {};
enum MenuResult { Nothing, Exit, Play };
const static GameObjectManager& GetGameObjectManager();
struct MenuItem
{
public:
sf::Rect<int> rect;
MenuResult action;
};
MenuResult Show(sf::RenderWindow& window);
static GameObjectManager _gameObjectManager;
Button button_play;
private:
MenuResult GetMenuResponse(sf::RenderWindow& window);
MenuResult HandleClick(int x, int y);
std::list<MenuItem> _menuItems;
};
MainMenu.cpp (this is quite long; I've only included the function that calls ButtonInit() and the function that Show() returns - if you need to see more, let me know and I can include the rest of the code for this file)
#include "stdafx.h"
#include "MainMenu.h"
#include "ServiceLocator.h"
#include "Button.h"
MainMenu::MenuResult MainMenu::Show(sf::RenderWindow& window)
{
button_play.ButtonInit("new-game");
return GetMenuResponse(window);
}
MainMenu::MenuResult MainMenu::GetMenuResponse(sf::RenderWindow& window)
{
sf::Event menuEvent;
while(42 != 43)
{
while(window.pollEvent(menuEvent))
{
if(menuEvent.type == sf::Event::MouseMoved)
{
button_play.Update(window);
}
if(menuEvent.type == sf::Event::MouseButtonPressed)
{
if(ServiceLocator::GetAudio()->IsSongPlaying())
{
ServiceLocator::GetAudio()->StopAllSounds();
}
return HandleClick(menuEvent.mouseButton.x,menuEvent.mouseButton.y);
}
if(menuEvent.type == sf::Event::Closed)
{
return Exit;
}
}
}
}
Button.h
#pragma once
class Button
{
public:
Button() {};
~Button() {};
void ButtonInit(std::string name);
void Update(sf::RenderWindow & rw);
};
Button.cpp
#include "StdAfx.h"
#include "Button.h"
void Button::ButtonInit(std::string name)
{
}
void Button::Update(sf::RenderWindow & rw)
{
}
stdafx.h (probably don't need to see this, but just in case)
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
#include <map>
#include <iostream>
#include <cassert>
#include <string>
Any help would be appreciated.

I assume, you have both classes in the same project.
The linker-message tells you, that the linker does not find a fitting function definition.
So my guess would be ... the linker cannot find a fitting overload of the function. "new-game" is a const char* and it is not a std::string.
a) change your method signature to
void ButtonInit(const char* name);
or
b) call your method like:
button_play.ButtonInit(std::string("new-game"));

Related

How do I avoid `already defined` linking error with pugixml if two static libs contain pugixml objs?

So I have 2 static libs defined like this:
StaticLib1
// StaticLib1.h
#pragma once
class StaticLib1
{
public:
void doSomething1();
};
cpp:
// StaticLib1.cpp
#include "pugixml.hpp"
#include "StaticLib1.h"
void StaticLib1::doSomething1()
{
pugi::xml_node node;
}
StaticLib2
// StaticLib2.h
#pragma once
class StaticLib2
{
public:
void doSomething2();
};
cpp:
// StaticLib1.cpp
#include "pugixml.hpp"
#include "StaticLib2.h"
void StaticLib2::doSomething2()
{
pugi::xml_node node;
}
Main
#include <iostream>
#include "StaticLib1.h"
#include "StaticLib2.h"
int main(int argv, char** argc)
{
StaticLib1 staticlib1;
StaticLib2 staticlib2;
staticlib1.doSemething1();
staticlib2.doSemething2();
getchar();
return 0;
}
Now, if I build this. I get a lot of linking errors. Here are the first few linking errors:
3>StaticLib2.lib(StaticLib2.obj) : error LNK2005: "public: __thiscall pugi::xml_attribute::xml_attribute(struct pugi::xml_attribute_struct *)" (??0xml_attribute#pugi##QAE#PAUxml_attribute_struct#1##Z) already defined in StaticLib1.lib(StaticLib1.obj)
3>StaticLib2.lib(StaticLib2.obj) : error LNK2005: "public: __thiscall pugi::xml_attribute::xml_attribute(void)" (??0xml_attribute#pugi##QAE#XZ) already defined in StaticLib1.lib(StaticLib1.obj)
3>StaticLib2.lib(StaticLib2.obj) : error LNK2005: "private: __thiscall pugi::xml_attribute_iterator::xml_attribute_iterator(struct pugi::xml_attribute_struct *,struct pugi::xml_node_struct *)" (??0xml_attribute_iterator#pugi##AAE#PAUxml_attribute_struct#1#PAUxml_node_struct#1##Z) already defined in StaticLib1.lib(StaticLib1.obj)
...
...
Now, I understand that this linking error is because there is a pugixml.obj inside StaticLib1.lib, and there is pugixml.obj inside StaticLib2.lib. But I don't understand why this would cause linking error with pugixml signatures. Why would they be defined twice? If I call staticlib1.doSomething1() shouldn't main not care if there are multiple definitions of pugi? Shouldn't staticlib1.doSomething1() handle all of that?
on the pugiconfig.hpp I have these specific settings:
#ifndef HEADER_PUGICONFIG_HPP
#define HEADER_PUGICONFIG_HPP
#define PUGIXML_WCHAR_MODE
#define PUGIXML_HEAD_ONLY
#include "pugixml.cpp"
#endif
So yes, from user0042advice, I realize it is better to compile a pugixml.lib on your own rather than having #include "pugixml.cpp" on the config. I'm working with legacy code so these surprises are there. Now, I've fixed my issue and made my company code slightly cleaner.

error LNK2005: quest_tree::enter_one(class quest_tree::quest_node * &,class std::basic_string<char,struct std::char_traits<char>

I've seen many posts on LNK2005 error, but decided to ask my own anyway.
Here is the error code:
1>setup_quest_tree.obj : error LNK2005: "private: void __thiscall quest_tree::enter_one(class quest_tree::quest_node * &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?enter_one#quest_tree##AAEXAAPAVquest_node#1#ABV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) already defined in mainFunction.obj
1>setup_quest_tree.obj : error LNK2005: "void __cdecl setup_quest_tree(void)" (?setup_quest_tree##YAXXZ) already defined in mainFunction.obj
1>C:\Users\Timothy\Documents\Visual Studio 2008\Projects\ttbag\Debug\TTBAG.exe : fatal error LNK1169: one or more multiply defined symbols found
I'm trying to get the program to compile but am running into linker errors while doing so, probably because I've included quest_tree.h twice, but when I got rid of one of the declarations of quest_tree.h in setup_quest_tree.cpp I run into this error:
1>c:\users\timothy\documents\visual studio 2008\projects\ttbag\ttbag\setup_quest_tree.cpp(8) : error C2065: 'quest_tree' : undeclared identifier
There are many files so I am only including the ones for my project that are related to the error.
setup_quest_tree.cpp:
#ifndef SETUP_QUEST_NODES_CPP
#define SETUP_QUEST_NODES_CPP
#include <string>
#include "quest_tree.h"
void setup_quest_tree() {
quest_tree quest_tree_obj; //start out with two quest nodes
std::string welcome_message = "debug-welcome message";
quest_tree_obj.enter(welcome_message);
}
#endif
setup_quest_tree.h:
#ifndef SETUP_QUEST_TREE_H
#define SETUP_QUEST_TREE_H
#include "quest_tree.h"
#include "setup_quest_tree.cpp"
//function declarations
void setup_quest_tree (quest_tree &quest_tree_obj);
#endif /* SETUP_QUEST_TREE_H */
mainFunction.cpp (just the include statements):
#define DEBUG_LINES_ON
#include <iostream>
#include <fstream>
#include <time.h>
#include "weather.h"
#include "item.h"
#include "map.h"
#include "person.h"
#include "location.h"
#include "bag.h"
#include "equipped_items.h"
#include "global_vars.h"
#include "setup_quest_tree.h"
int main() { ...
quest_tree.h:
#ifndef QUEST_TREE_H
#define QUEST_TREE_H
#include <string>
#include <cstdlib>
class quest_tree {
private:
// the basic node of the tree. Do way to read from file?
class quest_node {
private:
quest_node *quest_nodes; // pointer to array of quests that activate upon quest activation
public:
//std::string word; // we will replace this with our own data variable
std::string note_to_player; //note that is shown upon quest activation
/*
quest_node(){ // default constructor
note_to_player = "";
}
*/
quest_node(short int num_nodes = 2){
quest_nodes = new quest_node[num_nodes]; // problem: not declared in quest_tree but rather in quest_node
note_to_player = "";
}
friend class quest_tree;
};
// the top of the tree
quest_node * root;
// Enter a new node into the tree or sub-tree
void enter_one(quest_node *&node, const std::string& note_to_player);
public:
quest_tree() {root = NULL;} // constructor
// Add a new note_to_player to our tree
void enter(std::string& note_to_player) {
enter_one(root, note_to_player);
}
};
void quest_tree::enter_one(quest_node *&new_node, const std::string& note_to_player)
{
// see if we have reached the end
if (new_node == NULL) {
new_node = new quest_node;
for (short int index = 0; index < (sizeof(new_node->quest_nodes)/sizeof(new_node->quest_nodes[0])); index++) { // initialize quest_nodes
new_node->quest_nodes[index] = NULL;
}
new_node->note_to_player = note_to_player;
}
if (new_node->note_to_player == note_to_player)
return;
/*
if (new_node->note_to_player < note_to_player)
enter_one(new_node->right, word);
else
enter_one(new_node->left, word)
*/
}
#endif /* QUEST_TREE_H */
You have included the implementation in the setup_quest_tree.h header file
#include "setup_quest_tree.cpp"
and included it in several translation units.
To fix this, at least in setup_quest_tree.cpp just include the declarations from setup_quest_tree.h, and remove that #include "setup_quest_tree.cpp" statement from setup_quest_tree.h should fix your linker errors.
You have to provide exclusively one definition (implementation) for your class (see also this answer for "Is is a good practice to put the definition of C++ classes into the header file?").
If you put it there, just since you don't know how to add the setup_quest_tree.cpp to your program, check this Q&A please to learn more about the linking process.
Here's the relevant section from the current c++ standard
3.2 One definition rule [basic.def.odr]
1 No translation unit shall contain more than one definition of any variable, function, class type, enumeration
type, or template.

c++ unresolved external symbol when trying to compile program [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 9 years ago.
When trying to compile my program this error shows up:
Error 1 error LNK2001: unresolved external symbol "public: static class sf::Texture TextureManager::texture" (?texture#TextureManager##2VTexture#sf##A)
This is my code:
main.cpp:
int main()
{
TextureManager::Initialize();
}
TextureManager.h:
#include <SFML\Graphics.hpp>
using namespace sf;
class TextureManager
{
public:
static Texture texture;
public:
static void Initialize();
};
TextureManager.cpp:
#include <SFML\Graphics.hpp>
#include <iostream>
#include "TextureManager.h"
using namespace sf;
void TextureManager::Initialize()
{
if(!texture.loadFromFile("Textures\\Blocks\\Texture.png"))
{
std::cout << "Error!";
}
else
{
std::cout << "Sucess!";
}
}
I've tried searching for any solutions (including this site) but have not found any.
When you have a static member in C++, you should define it in your .cpp :
static Texture Texture::texture;
This is because static members must be defined in exactly one translation unit, in order to not violate the One-Definition Rule.
You can do it at the top of your TextureManager.cpp:
#include <SFML\Graphics.hpp>
#include <iostream>
#include "TextureManager.h"
using namespace sf;
static Texture Texture::texture; // <-
void TextureManager::Initialize()
{
}

C++ "unresolved external symbol" using namespace from different project

I have two projects (call them Test and Intrados). Inside Intrados, I have the following namespace:
#include "Mapper.h"
#include "Director.h"
#include "Driver.h"
#include <iostream>
#include <string>
using namespace std;
namespace IntradosMediator {
void addVehicle(string);
}
void IntradosMediator::addVehicle(string vehicleName) {
Mapper* mapper = Mapper::getInstance();
mapper->addVehicle(vehicleName);
}
From within the Intrados project, calling "IntradosMediator::Mapper(addVehicle)" works just fine; yet, in project Test, the following code produces a link error:
#include "IntradosMediator.cpp"
#include "Mapper.h"
using namespace IntradosMediator;
int main(){
IntradosMediator::addVehicle("Car X");
return 0;
}
The error is:
Test.obj : error LNK2019: unresolved external symbol "public: static class Mapper *
__cdecl Mapper::getInstance(void)" (?getInstance#Mapper##SAPAV1#XZ) referenced in
function "void __cdecl IntradosMediator::addVehicle(class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> >)"
(?addVehicle#IntradosMediator##YAXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##
std###Z)
I've made sure to add Intrados as a reference for Test, and also included it in the Include Directories. Not sure what to do here, since I'm new to C++. Thanks in advance for any advice.
Edit:
I'm adding the Mapper code here:
//.h
#ifndef MAPPER_H
#define MAPPER_H
#include <string>
using std::string;
class Mapper {
public:
static Mapper* getInstance();
void addVehicle(string);
private:
//this is a singleton
Mapper(){};
};
#endif
//.cpp
#include "Mapper.h"
#include <vector>
#include <iostream>
#include <string>
using namespace std;
vector<string> vehicleList;
Mapper* Mapper::getInstance(){
static Mapper instance;
return &instance;
}
void
Mapper::addVehicle(string vehicleName) {
vehicleList.push_back(vehicleName);
}
The error says the linker can't find Mapper::getInstance (it seems to find your addVehicle function just fine). Might you be failing to include the library that implements "Mapper" in your link?
Could you paste your code for class Mapper?
It seems like you are missing addVehicle function in that class, which is what the compiler is complaining about.

Unresolved external symbol with custom blocking queue implementation

I have created my own blocking queue and I'm having some trouble figuring out why I get a linker error (note this is a Qt app in Visual Studio 2010):
#ifndef BLOCKING_QUEUE_H
#define BLOCKING_QUEUE_H
#include <QObject>
#include <QSharedPointer>
#include <QWaitCondition>
#include <QMutex>
#include <queue>
namespace TestingNS
{
template<typename Data>
class BlockingQueue
{
private:
std::queue<QSharedPointer<Data>> _queue;
QMutex _mutex;
QWaitCondition _monitor;
volatile bool _closed;
public:
BlockingQueue();
void Close();
size_t Size();
void Empty();
bool IsClosed();
bool Enqueue(QSharedPointer<Data> data);
bool TryDequeue(QSharedPointer<Data>& value, unsigned long time = ULONG_MAX);
};
}
#endif //BLOCKING_QUEUE_H
The implementation is a bit longer, so I have a pastie for it: http://pastie.org/5368660
The program entry point looks like this:
#include <QtCore/QCoreApplication>
#include <QTimer>
#include <iostream>
#include "BlockingQueue.h"
using namespace std;
using namespace TestingNS;
class Item
{
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
BlockingQueue<Item> queue;
cout << "Press any key to exit!" << endl;
char in;
cin.get(in);
QTimer::singleShot(0, &a, SLOT(quit()));
return a.exec();
}
The linker error I get is:
Error 1 error LNK2019: unresolved external symbol "public: __thiscall TestingNS::BlockingQueue<class Item>::BlockingQueue<class Item>(void)" (??0?$BlockingQueue#VItem###TestingNS##QAE#XZ) referenced in function _main
I don't understand why the linker can't find the constructor (nor any other method from BlockingQueue). Any ideas?
It's template, you have to put the implementation inside BlockingQueue.h
For a while, the standard did
provide the keyword export to allow such a separate implementation file. But not many
vendors implemented it. C++11 discontinues that use of export but reserves the export
keyword for possible future use.)
Templates have to be used in conjunction with requests for particular
instantiations of templates.