Calling a Static Method, Getting error: LNK2019 - c++

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)
{
...
}

Related

namespace extern variable already defined

I cannot compile my C++ program and I don't understand why.
Here's a simple representation of what is throwing errors:
hello/hello.cpp
#include "hello.h"
namespace MyHelloNS {
MyHelloClass::MyHelloClass() {
MyHelloVAR1 = "hi";
MyHelloVAR2 = "dog";
}
}
hello/hello.h
#pragma once
#include <string>
using namespace std;
namespace MyHelloNS {
extern string MyHelloVAR1;
extern string MyHelloVAR2;
class MyHelloClass;
}
class MyHelloNS::MyHelloClass {
public:
MyHelloClass();
};
main.cpp
#include "hello/hello.h"
int main() {
MyHelloNS::MyHelloClass hi1;
}
I get two kinds of errors:
unresolved external symbol in hello.obj
What's wrong?
Add this to main.cpp (or hello.cpp)
namespace MyHelloNS {
string MyHelloVAR1;
string MyHelloVAR2;
}
This question has nothing to do with namespaces, you just aren't following the correct procedure to define a global variable.

error while using std:sort on vector of objects [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 3 years ago.
I have a vector of Person object pointers. I am trying to use std:sort to sort the vector based on the "name" of each object. I am getting an unresolved external symbol error when I try to build and run; can anyone see where I am going wrong? error:
Error LNK2019 unresolved external symbol "public: static bool __cdecl Person::sortByName(class Person *,class Person *)" (?sortByName#Person##SA_NPAV1#0#Z) referenced in function _main Lab1b C:\Users\jayjo\source\repos\Lab1b\Lab1b\Lab1b.obj 1
error
Main cpp:
#include <iostream>
#include "Person.h"
#include "Employee.h"
#include "Customer.h"
#include <vector>
#include <algorithm>
int main()
{
vector<Person*> people;
people.push_back(new Person("Peter"));
people.push_back(new Person("John"));
people.push_back(new Person("David"));
people.push_back(new Person("Aaron"));
sort(people.begin(), people.end(), Person::sortByName);
for (int i = 0; i < people.size(); i++)
{
cout << people[i]->getName() << endl;
}
}
Person.h:
#pragma once
#ifndef Person_H
#define Person_H
using namespace std;
#include <iostream>
class Person
{
public:
Person(string);
virtual void printname();
static bool sortByName(Person* A, Person* B);
string getName();
protected:
string name;
};
#endif // !Person_H
Person.cpp:
#include "Person.h"
using namespace std;
Person::Person(string n)
{
name = n;
}
void Person::printname()
{
cout << "Name: " << name << endl;
}
string Person::getName()
{
return name;
}
static bool sortByName(Person* A, Person* B)
{
return (A->getName().compare(B->getName()));
}
Instead of this:
static bool sortByName(Person* A, Person* B)
{
return (A->getName().compare(B->getName()));
}
This:
bool Person::sortByName(Person* A, Person* B)
{
return (A->getName().compare(B->getName()) != 0);
}
In C++, you declare the class member function as static, but you leave the static keyword off when you define it. Also, the function needs to be defined as a class member (Person::).

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.

Really basic class won't build

Can someone please tell me what is wrong with this code? I don't get it at all..
I am trying to generate an object out of class "T_Tsunami".
The errors I get are:
"error LNK2019: unresolved external symbol "public: __thiscall T_Tsunami::~T_Tsunami(void)" (??1T_Tsunami##QAE#XZ) referenced in function _main"
and
"fatal error LNK1120: 1 unresolved externals".
Header:
#include <string>
using std::string;
#include<vector>
class T_Tsunami
{
public:
// Constructor with default arguments
T_Tsunami (const int nl = 100, const string="T_Tsunami");
~T_Tsunami(); // destructor
void setNL(int);
void setNaam(string);
private:
string Naam;
int Golf_NL;
};
cpp-file:
#include <vector>
#include <iostream>
#include <fstream>
#include <cmath>
#include "T_Tsunami.h"
T_Tsunami::T_Tsunami (const int nl, const string nieuwe_naam)
{
setNL(nl);
setNaam(nieuwe_naam);
}
void T_Tsunami::setNL(int nl)
{
Golf_NL = nl;
}
void T_Tsunami::setNaam(string nieuwe_naam)
{
Naam = nieuwe_naam;
}
Main:
#include <vector>
#include <iostream>
#include <fstream>
#include <cmath>
#include"T_Tsunami.h"
int main() {
T_Tsunami myTsunami;
}
Also I don't know if I need to put a return statement in the main, I did try that but it doesn't solve my problem.
You did not define the destructor, such as:
T_Tsunami::~T_Tsunami()
{
}

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.