I'm trying to get started with C++ in VS 2017 (empty project template), but immediately ran into linker problems when adding 1 simple class, so I guess I'm missing something important...
My project looks like this:
test.h:
#include <iostream>
class test
{
public:
test();
~test();
std::string getInfo();
};
test.cpp:
#include "test.h"
test::test() {}
test::~test() {}
std::string getInfo() {
return "test";
}
And main.cpp:
#include <iostream>
#include <string>
#include "test.h"
int main(int argc, char **argv) {
test t;
std::cout << "output: " << t.getInfo() << std::endl;
return 0;
}
The linker error I get is the infamous LNK2019:
LNK2019 unresolved external symbol "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl test::getInfo(void)" (?getInfo#test##QEAA?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ) referenced in function main
Any ideas what I am doing wrong here?
Thanks!
In file test.cpp you need to properly specify the scope of the member function:
std::string test::getInfo() {
return "test";
}
Note the test:: before the getInfo()
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've looked at other people's solutions to this problem and none of them, unfortunately, have solved my issue. I was having this error in my dev project, so I started from scratch, followed this tutorial to the letter, including the file names and locations, and I am still getting
1>unittest1.obj : error LNK2019: unresolved external symbol "public:
static int __cdecl HelloWorld::getTwo(void)"
(?getTwo#HelloWorld##SAHXZ) referenced in function "public: void
__thiscall UnitTest1::UnitTest1::TestMethodGetTwo(void)" (?TestMethodGetTwo#UnitTest1#1#QAEXXZ)
1>unittest1.obj : error
LNK2019: unresolved external symbol "public: int __thiscall
HelloWorld::getN(void)const " (?getN#HelloWorld##QBEHXZ) referenced in
function "public: void __thiscall
UnitTest1::UnitTest1::TestMethodGetN(void)"
(?TestMethodGetN#UnitTest1#1#QAEXXZ)
The code is in the tutorial I linked but I will copy it below. I don't understand what I could be doing wrong at this point - my test project depends on my build project, my definitions for these functions are in the class.
HelloWorld.h
#pragma once
class HelloWorld
{
int n = 10;
public:
static int getTwo();
int getN() const;
};
HelloWorld.cpp
#include "stdafx.h"
#include "HelloWorld.h"
int main()
{
return 0;
}
int HelloWorld::getTwo()
{
return 2;
}
int HelloWorld::getN() const
{
return n;
}
unittest1.cpp (in test project)
#include "stdafx.h"
#include "CppUnitTest.h"
#include "../HelloWorld/HelloWorld.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace UnitTest1
{
TEST_CLASS(UnitTest1)
{
public:
TEST_METHOD(TestMethodGetTwo)
{
Assert::AreEqual(2, HelloWorld::getTwo());
}
TEST_METHOD(TestMethodGetN)
{
HelloWorld hw = HelloWorld();
Assert::AreNotEqual(0, hw.getN());
}
};
}
For some reason the linker can't find my definitions, and I'm out of ideas about why that might be.
I am trying to create a solution which one project is the .exe and the other project is a simple dll. What i am trying to learn is how to link between two projects. I have searched stack-overflow and found really nice answers which I have followed, such as declaring the right header bath on:
Properties->Configuration Properties->C/C++->General->Additional Include Directories
Then setting the .lib on:
Properties->Configuration Properties->Linker->Input->Additional Dependencies
I used macros to generate that .lib file also. Here is the my simplified code:
The .exe:
cpp:
#include "stdafx.h"
#include "../ConsoleApplication2/HelloWorld.h"
int _tmain(int argc, _TCHAR* argv[])
{
hello_world hw;
hw.printHello();
getchar();
return 0;
}
The dll:
header:
#pragma once
#ifdef is_hello_world_dll
#define hello_world_exp __declspec(dllexport)
#else
#define hello_world_exp __declspec(dllimport)
#endif
class hello_world_exp hello_world
{
public:
hello_world();
~hello_world();
void printHello();
};
cpp:
#include "stdafx.h"
#include "HelloWorld.h"
#include <iostream>
hello_world::hello_world()
{
}
hello_world::~hello_world()
{
}
void printHello()
{
std::cout << "Hello World" << std::endl;
}
A note: The solution compiles fine when I don't call hw.printHello(); however when I do call it, the linker generates :
Error 1 error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __thiscall hello_world::printHello(void)" (__imp_?printHello#hello_world##QAEXXZ) referenced in function _wmain C:\Users\usteinfeld\Desktop\Private\Students\Yana\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.obj ConsoleApplication1
This function is defined as a free function based on how you wrote it
void printHello()
It belongs to the class hello_world so you should scope it as such
void hello_world::printHello()
{
std::cout << "Hello World" << std::endl;
}
I have a multi-file project in VSC++2010, but for some reason it won't link some of them properly.
For example, I have CParser.h and CParser.cpp . CParser.h is just some function declarations:
#pragma once
#include <string>
void parseArg(int argc, char* argv[], GVar gv);
void parseCfg(string cfg, GVar gv)
CParser.cpp just contains implementations:
#include <cstdio>
#include <fstream>
#include <cstring>
#include <string>
#include "_GlobalVar.h" //defines GVar, not relevant
#include "CParser.h"
void parseArg(int argc, char* argv[], GVar &gv) {
/*not really relevant*/
}
And the error:
main.obj : error LNK2019: unresolved external symbol "void __cdecl
parseArg(int,char * * const,class GVar)"
(?parseArg##YAXHQAPADVGVar###Z) referenced in function _SDL_main
Edit:
There's also this other problem:
template<class T>
void RDAMHandler<T>::clean() {
long i;
while(!avtick.empty())
avtick.pop();
for(i = v.size() - 1; i >= 0; i--) {
delete all[i];
all.pop_back();
v.pop_back();
}
}
And the declaration:
template<class T>
class RDAMHandler {
vector<T*> all;
priority_queue<long> avtick;
vector<bool> v;
public:
T &operator[](long x);
long insert(T &x);
void del(long x);
void clean();
};
I don't see any difference here; what is the problem?
Edit edit: And error
main.obj : error LNK2019: unresolved external symbol "public: void
__thiscall RDAMHandler::clean(void)" (?clean#?$RDAMHandler#USDL_Surface####QAEXXZ) referenced in function
"void __cdecl cleanUp(class GVar)" (?cleanUp##YAXVGVar###Z)
In CParser.cpp
I think You have to use statement
void CParser::parseArg(int argc, char* argv[], GVar &gv)
instead of
void parseArg(int argc, char* argv[], GVar &gv) in CParser.cpp file
And In CParser.h
The declaration should be changed to void parseArg(int argc, char* argv[], GVar &gv);
And For Next Error
For Reference Please Go through this
1. Template using class
Hope this will help you.
They're two different overloads - the declaration in the header has GVar gv, while the definition in the .cpp file has GVar &gv. One of these is probably a typo.
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.