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.
Related
I'm having some troubles making a string utility class that has only static methods. Whenever I use a calling class to use a static method in my string utility class, it compiles with an LNK error, 2019. Any help would be much appreciated.
.h is below,
#pragma once
#include <string>
#include "stdafx.h"
#include <iostream>
using namespace std;
static class StringUtil
{
public:
static string Reverse(string);
// bool Palindrome(string);
// string PigLatin(string);
// string ShortHand(string);
private:
// string CleanUp(string);
};
.cpp file is below,
#include "StdAfx.h"
#include "StringUtil.h"
#include <iostream>
static string Reverse(string phrase)
{
string nphrase = "";
for(int i = phrase.length() - 1; i > 0; i--)
{
nphrase += phrase[i];
}
return nphrase;
}
and below is the calling class.
#include "stdafx.h"
#include <iostream>
#include "StringUtil.h"
void main()
{
cout << "Reversed String: " << StringUtil::Reverse("I like computers!");
}
And when it runs, it shows
Error 5 error LNK2019: unresolved external symbol "public: static class std::basic_string,class std::allocator > __cdecl StringUtil::Reverse(class std::basic_string,class std::allocator >)" (?Reverse#StringUtil##SA?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##V23##Z) referenced in function "void __cdecl a10_StringUtil(void)" (?a10_StringUtil##YAXXZ) H:\Visual Studio 2010\Projects\Object Oriented C++\Object Oriented C++\Object Oriented C++.obj Object Oriented C++
and
Error 6 error LNK1120: 1 unresolved externals H:\Visual Studio 2010\Projects\Object Oriented C++\Debug\Object Oriented C++.exe 1 1 Object Oriented C++
I feel like this is a very simple problem, but I'm used to programming in Java. I'm trying to teach myself how to code in c++ currently, hence my problem.
First of all in C++ we do not have static classes:
#pragma once
#include <string>
#include "stdafx.h"
#include <iostream>
using namespace std;
class StringUtil
{
public:
static string Reverse(string);
// bool Palindrome(string);
// string PigLatin(string);
// string ShortHand(string);
private:
// string CleanUp(string);
};
Second you forgot the class name StringUtil (owner):
string StringUtil::Reverse(string phrase)
{
string nphrase = "";
for(int i = phrase.length() - 1; i >= 0; i--)
{
nphrase += phrase[i];
}
return nphrase;
}
I hope this helps you :)
static string Reverse(string phrase)
{
...
}
does not define the static member function of the class. It defines a file scoped non-member function. You need to use:
string StringUtil::Reverse(string phrase)
{
...
}
I'm developing a C++ solution with Visual Studio 2015.
I have a cpp source file and header file hpp with this declaration.
Header:
#ifndef MyLib__FREEFUNCTIONS__INCLUDE__
#define MyLib__FREEFUNCTIONS__INCLUDE__
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
// Check if 'str' is null, empty or consists only of white-space characters.
inline bool IsNullOrWhiteSpace(string str);
// More functions
[ ... ]
#endif
And Source code:
#include "FreeFunctions.h"
inline bool IsNullOrWhiteSpace(string str)
{
return (str.empty() || (str.find_first_not_of(' ') == string::npos));
}
I use this function in a class:
#include "ConvertToOwnFormat.h"
#include "FreeFunctions.h"
ConvertToOwnFormat::ConvertToOwnFormat()
{
}
ConvertToOwnFormat::~ConvertToOwnFormat()
{
}
vector<Entry> ConvertToOwnFormat::ReadCatalogue(string path)
{
if (!IsNullOrWhiteSpace(path)
{
[ ... ]
}
}
And I get the following error in ConvertToOwnFormat::ReadCatalogue:
Error LNK2019 external symbol "bool __cdecl IsNullOrWhiteSpace(class
std::basic_string,class
std::allocator >)"
(?IsNullOrWhiteSpace##YA_NV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
unresolved referenced by the function "public: class std::vector > __cdecl
ConvertToOwnFormat::ReadCatalogue(class std::basic_string,class std::allocator >)"
(?ReadCatalogue#ConvertToOwnFormat##QEAA?AV?$vector#VEntry##V?$allocator#VEntry###std###std##V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##3##Z) MyProjectLib D:\Fuentes\Repos\MyProject\MyProjectLibConsoleTest\ConsoleMyProjectLib\Lib.lib(ConvertToOwnFormat.obj) 1
You have to put declaration of methods within the header. inline tells to compiler that it should replace call of function with the core of function. So, it need it at compilation time for every unit of compilation which use it
#ifndef MyLib__FREEFUNCTIONS__INCLUDE__
#define MyLib__FREEFUNCTIONS__INCLUDE__
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
// Check if 'str' is null, empty or consists only of white-space characters.
inline bool IsNullOrWhiteSpace(std::string str)
{
return (str.empty() || (str.find_first_not_of(' ') == std::string::npos));
}
// Others functions, prototype, ...
#endif
or remove inline in both source and header files
It's totally out of topic but never put a using namespace inside a header: a header should offer something but should not impose something like namespace. See also "using namespace" in c++ headers
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"));
I am using VS2013 and I have a static lib project with the following header:
#pragma once
namespace StaticLibNamespace
{
void foo( void );
}
Then the function is defined in the cpp as follows:
#include "stdafx.h"
#include "StaticLibHeader.h"
using namespace StaticLibNamespace;
void foo( void )
{
;
}
In my simple console app, I include the reference to StaticLibNameSpaceTest.lib and my main function is the following:
#include "stdafx.h"
#include "..\StaticLibNamespaceTest\StaticLibHeader.h"
int _tmain(int argc, _TCHAR* argv[])
{
StaticLibNamespace::foo();
return 0;
}
If I try and compile this I get the following error:
NamespaceTest.obj : error LNK2019: unresolved external symbol "void __cdecl StaticLibNamespace::foo(void)" (?foo#StaticLibNamespace##YAXXZ) referenced in function _wmain
However if I change my static lib cpp file to the following everything is fine:
#include "stdafx.h"
#include "StaticLibHeader.h"
void StaticLibNamespace::foo( void )
{
;
}
I'm obviously not understanding everything going on with "using namespace" can someone please enlighten me? Thanks!
The using namespace directive changes the lookup rules for symbols when the compiler sees an unqualified name and needs to find what it refers to.
However, in your case, you are defining a new function called foo. As an unqualified name, this defines a new foo in the global namespace (assuming there wasn't already one there). When you qualify the name, you are defining StaticLibNamespace::foo as you intend.
A different solution might be:
namespace StaticLibNamespace {
void foo( void )
{
;
}
} // namespace StaticLibNamespace
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()
{
}