This question already has answers here:
C++ "fatal error LNK1120" unresolved static class members
(2 answers)
Closed 5 years ago.
I have a class EventType, which has the following header (relevant lines only):
#include<string>
#include<unordered_set>
#include<iostream>
class EventType
{
public:
static EventType* getByName(std::string name);
static EventType* getByID(std::string id);
static void setAllEventTypes(std::unordered_set<EventType*> events);
//...
private:
static std::unordered_set<EventType*> allEvents; //stores all events
std::string name;
//...
std::string akaID;
};
And the source:
EventType* EventType::getByName(std::string name) {
foreach(EventType * event, EventType::allEvents) {
if(event->name == name) {
return event;
}
}
std::cout << "Error: Event with name " << name << "could not be found.\n";
}
EventType* EventType::getByID(std::string id) {
foreach(EventType * event, EventType::allEvents) {
if(event->akaID == id) {
return event;
}
}
std::cout << "Error: Event with aka.ID " << id << "could not be found.\n";
}
void EventType::setAllEventTypes(std::unordered_set<EventType*> events) {
EventType::allEvents = events;
}
Now I'm getting the LNK2001-error:
eventtype.obj : error LNK2001: unresolved external symbol ""private: static class std::unordered_set<class EventType *,struct std::hash<class EventType *>,struct std::equal_to<class EventType *>,class std::allocator<class EventType *> > EventType::allEvents" (?allEvents#EventType##0V?$unordered_set#PEAVEventType##U?$hash#PEAVEventType###std##U?$equal_to#PEAVEventType###3#V?$allocator#PEAVEventType###3##std##A)".
I get this error even when I'm not using any of the static methods from outside my EventType-class. Why does this happen? Shouldn't EventType be able to link to itself?
You declared allEvents but did not define it, you need to do that in your source file:
std::unordered_set<EventType*> EventType::allEvents;
Let's take this snippet code :
class MyClass
{
public:
int m_num;
MyClass(int n) { m_num = n;}
}
If I create an object of this class the following way :
MyClass mc1(5);
MyClass mc2(mc1);
This calls to the default copy-constructor and it'll automatically assign mc2.m_num = mc1.m_num ?
Also if there's a call inside the class which makes an instance the following way :
MyClass mc3(*this);
This will call to the default copy-constructor same as with mc2 the *this is just getting the object itself to be copied ?
Second problem I'm having is with compiling my code with Microsoft Visual Studio 2013.
I've made a String class and when I try to compile I get lot's of linking error telling me that the functions are already defined for some reason.
String.h :
#pragma once
class String
{
private:
char* m_szStr;
unsigned int m_length;
public:
String(const char*);
explicit String(unsigned int);
String(const String&);
~String();
String& operator=(const String&);
bool operator==(const String&) const;
String operator+(const String&) const;
operator const char*() const;
int findStr(char*) const;
int getLen() const;
void copyStr(const char*);
};
String.cpp:
#include "stdafx.h"
#include "String.h"
String::String(const char* pch)
{
m_szStr = NULL;
copyStr(pch);
}
String::String(unsigned int len)
{
m_length = len;
m_szStr = new char[m_length];
}
String::String(const String& that)
{
copyStr(that.m_szStr);
}
String::~String()
{
delete[] m_szStr;
}
String& String::operator=(const String& that)
{
copyStr(that.m_szStr);
return *this;
}
bool String::operator==(const String& that) const
{
if (m_length != that.m_length)
return false;
for (unsigned int i = 0; i < m_length; i++)
{
if (m_szStr[i] != that.m_szStr[i])
return false;
}
return true;
}
String String::operator+(const String& that) const
{
String temp(m_length + that.m_length - 1);
unsigned int offset = m_length;
for (unsigned int i = 0; i < that.m_length; i++)
{
temp.m_szStr[offset] = that.m_szStr[i];
}
return temp;
}
String::operator const char*() const
{
return m_szStr;
}
int String::findStr(char* pch) const
{
unsigned int offset = 0;
unsigned int strIndex = -1;
for (unsigned int i = 0; m_szStr[i] != NULL && pch[offset] != NULL; i++)
{
if (m_szStr[i] == pch[offset])
{
if (strIndex == -1)
strIndex = i;
offset++;
}
else
{
strIndex = -1;
offset = 0;
}
}
return strIndex;
}
int String::getLen() const
{
unsigned int len = 0;
for (unsigned int i = 0; m_szStr[i] != NULL; i++)
{
len++;
}
return len;
}
void String::copyStr(const char* pch)
{
if (!m_szStr)
delete[] m_szStr;
unsigned int pchLen = 0;
for (unsigned int i = 0; pch[i] != NULL; i++)
{
pchLen++;
}
m_length = pchLen;
m_szStr = new char[m_length];
for (unsigned int i = 0; i < m_length; i++)
{
m_szStr[i] = pch[i];
}
}
Code file:
#include "stdafx.h"
#include <iostream>
#include "String.cpp"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])s
{
String s1("Hi!");
String s2(5);
s2 = "Hello, Hi!";
const char* pch = static_cast<const char*>(s2);
cout << pch << endl;
return 0;
}
errors:
Error 1 error LNK2005: "public: __thiscall String::String(class String const &)" (??0String##QAE#ABV0##Z) already defined in assignment4.obj C:\Users\****\Desktop\C++ Programming\assignment4\assignment4\String.obj assignment4
Error 2 error LNK2005: "public: __thiscall String::String(unsigned int)" (??0String##QAE#I#Z) already defined in assignment4.obj C:\Users\****\Desktop\C++ Programming\assignment4\assignment4\String.obj assignment4
Error 3 error LNK2005: "public: __thiscall String::String(char const *)" (??0String##QAE#PBD#Z) already defined in assignment4.obj C:\Users\****\Desktop\C++ Programming\assignment4\assignment4\String.obj assignment4
Error 4 error LNK2005: "public: __thiscall String::~String(void)" (??1String##QAE#XZ) already defined in assignment4.obj C:\Users\****\Desktop\C++ Programming\assignment4\assignment4\String.obj assignment4
Error 5 error LNK2005: "public: class String & __thiscall String::operator=(class String const &)" (??4String##QAEAAV0#ABV0##Z) already defined in assignment4.obj C:\Users\****\Desktop\C++ Programming\assignment4\assignment4\String.obj assignment4
Error 6 error LNK2005: "public: bool __thiscall String::operator==(class String const &)const " (??8String##QBE_NABV0##Z) already defined in assignment4.obj C:\Users\****\Desktop\C++ Programming\assignment4\assignment4\String.obj assignment4
Error 7 error LNK2005: "public: __thiscall String::operator char const *(void)const " (??BString##QBEPBDXZ) already defined in assignment4.obj C:\Users\****\Desktop\C++ Programming\assignment4\assignment4\String.obj assignment4
Error 8 error LNK2005: "public: class String __thiscall String::operator+(class String const &)const " (??HString##QBE?AV0#ABV0##Z) already defined in assignment4.obj C:\Users\****\Desktop\C++ Programming\assignment4\assignment4\String.obj assignment4
Error 9 error LNK2005: "public: void __thiscall String::copyStr(char const *)" (?copyStr#String##QAEXPBD#Z) already defined in assignment4.obj C:\Users\****\Desktop\C++ Programming\assignment4\assignment4\String.obj assignment4
Error 10 error LNK2005: "public: int __thiscall String::findStr(char *)const " (?findStr#String##QBEHPAD#Z) already defined in assignment4.obj C:\Users\****\Desktop\C++ Programming\assignment4\assignment4\String.obj assignment4
Error 11 error LNK2005: "public: int __thiscall String::getLen(void)const " (?getLen#String##QBEHXZ) already defined in assignment4.obj C:\Users\****\Desktop\C++ Programming\assignment4\assignment4\String.obj assignment4
Error 12 error LNK1169: one or more multiply defined symbols found C:\Users\****\Desktop\C++ Programming\assignment4\Debug\assignment4.exe 1 1 assignment4
In your main code file, write:
#include "String.h" // with .cpp you redefine everything !!
Currently you include String.cpp. So in your main file you will redefine everything you have already defined in String.cpp. It will compile, but the linker will be confused because he will find a definition for your String member functions in String.obj as well as in main.obj ("one definition rule").
And you already answerd yourself your copy constructor question
I have written this code using SDL but there are some errors.
This is the code
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <SDL_mixer.h>
#include <fstream>
#include <iostream>
using namespace std;
/////////////////////////////////// functions & global variable ////////////////////////////////
SDL_Window* window;
SDL_Renderer* renderer;
SDL_Color textColor;
TTF_Font* font;
SDL_Surface* surface=SDL_GetWindowSurface(window);
SDL_Event event;
SDL_Texture* LoadTexture(char* path)
{
SDL_Surface* surface = IMG_Load(path);
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer,surface);
SDL_FreeSurface(surface);
return texture;
}
///////////////////////////////////// Cell /////////////////////////////////////
class Cell
{
private:
char num;
public:
Cell();
Cell(int ,int ,char);
char * img;
pair <int ,int> cor;
int flag;
int size;
void display();
bool indomain(int ,int);
};
Cell :: Cell(int x ,int y ,char n){
num=n;
cor.first=x;
cor.second=y;
size=40;
flag=0;
if (num == '#')
img="0.png";
else if (num == '!')
img="1.png";
else
img="street.png";
}
bool Cell :: indomain(int x ,int y){
if ( (cor.first<=x && x<=cor.first+size) && (cor.second<=y && y<=cor.second+size))
return true;
return false;
}
void Cell :: display(){
SDL_Rect rect;
rect.x=cor.first;
rect.y=cor.second;
SDL_Texture* texture = LoadTexture(img);
SDL_RenderCopy(renderer,texture,NULL,&rect);
}
//////////////////////////////////////////// Tower /////////////////////////////////////////
class Tower
{
public:
Tower();
Tower(int ,int ,int ,int ,char* ,int ,int ,int);
~Tower();
int price;
int up_cost;
char * img;
int power;
int domain;
int grade;
int index;
pair <int ,int> cor;
void upgrade();
void display();
bool mark(int ,int);
};
Tower :: Tower(int pr ,int co ,int pow ,int dom ,char* im ,int x ,int y ,int i){
price=pr;
up_cost=co;
power=pow;
domain=dom;
img=im;
cor.first=x;
cor.second=y;
grade=1;
index=i;
}
void Tower :: upgrade(){
if (grade<5)
{
grade+=1;
power*=2;
domain*=1.2;
price*=1.2;
}
}
void Tower :: display(){
SDL_Rect rect;
rect.x=cor.first;
rect.y=cor.second;
SDL_Texture* texture = LoadTexture(img);
SDL_RenderCopy(renderer,texture,NULL,&rect);
}
bool Tower :: mark(int x, int y){
if ((cor.first<=x && x<=cor.first+40) && (cor.second<=y && x<=cor.second+80))
return true;
return false;
}
//////////////////////////////// Enemy //////////////////////////////////////
class Enemy
{
public:
Enemy();
Enemy(int ,char* ,int ,int ,int);
~Enemy();
char * img;
int health;
int cellNum;
int index;
pair <int ,int> cor;
bool live();
void display();
void damge(Tower t);
};
Enemy :: Enemy(int h ,char* im ,int x ,int y ,int i){
health=h;
img=im;
cor.first=x;
cor.second=y;
cellNum=0;
index=i;
}
bool Enemy :: live(){
if (health>0)
return true;
return false;
}
void Enemy :: damge(Tower t){
health-=t.power;
}
void Enemy :: display(){
SDL_Rect rect;
rect.x=cor.first;
rect.y=cor.second;
SDL_Texture* texture = LoadTexture(img);
SDL_RenderCopy(renderer,texture,NULL,&rect);
}
///////////////////////////////////////////// Map ///////////////////////////////////////
class Map
{
private:
char * file;
int len;
public:
Map();
Map(char* ,int);
~Map();
Cell map[15][20];
pair <int ,int> * path;
void display();
void put_tower(Tower ,Cell);
void put_enemy(Enemy ,Cell);
void remove(Cell);
void enemyMove(Enemy);
void pathFinder(int);
};
Map :: Map(char * f ,int l){
file=f;
len=l;
ifstream infile;
infile.open(file);
char * line=new char;
for (int i=0;i<15;i++)
{
infile >> line;
for (int j=0;j<20;j++)
map[i][j]=Cell(j*40 ,i*40 ,line[j]);
}
this->pathFinder(len);
}
void Map :: put_enemy(Enemy e ,Cell c){
e.cor=c.cor;
e.display();
}
void Map :: put_tower(Tower t ,Cell c){
t.cor=c.cor;
t.display();
}
void Map :: remove(Cell c){
c.display();
}
void Map :: enemyMove(Enemy e){
e.cellNum+=1;
e.cor=path[e.cellNum];
}
void Map :: pathFinder(int l){
path=new pair<int ,int> [l];
ifstream infile;
infile.open(file);
char ** lines=new char* [15];
for (int i=0;i<15;i++)
infile >> lines[i];
for (int i=0;i<20;i++)
if (lines[0][i]=='0')
{
path[0]=make_pair(0,i);
break;
}
int x=0;
int y=path[0].second;
int ord=48;
for (int i=1;i<l;i++)
{
if (int(lines[x-1][y])==((ord-47)%10)+48)
x-=1;
else if (int(lines[x+1][y])==((ord-47)%10)+48)
x+=1;
else if (int(lines[x][y-1])==((ord-47)%10)+48)
y-=1;
else if (int(lines[x][y+1])==((ord-47)%10)+48)
y+=1;
path[i]=make_pair(x,y);
ord+=1;
}
}
void Map :: display(){
for (int i=0;i<15;i++)
for (int j=0;j<20;j++)
map[i][j].display();
}
//////////////////////////////////////////////////// Game ////////////////////////////////////////
class Game
{
private:
int health;
int money;
int score;
int step;
public:
Game(int ,int);
~Game();
bool End;
int enemyNum;
int towerNum;
Enemy enemys[20];
Tower towers[50];
int getHealth();
int getMoney();
int getScore();
int getStep();
void setHealth(int);
void setMoney(int);
void setScore(int);
void setStep(int);
void distroy_enemy(Enemy ,Cell);
void distroy_tower(Tower ,Cell);
void shooting(Tower);
void drag_drop(Tower);
void upgradeTower(Tower);
void buyTower(Tower);
void sellTower(Tower ,Cell);
void display(Map);
void displayMenu();
void endDisplay();
bool checkEnd();
void animation();
};
Game :: Game(int h ,int m){
health=h;
money=m;
step=1;
score=0;
enemyNum=0;
towerNum=0;
End=false;
}
int Game :: getHealth(){
return health;
}
int Game :: getMoney(){
return money;
}
int Game :: getScore(){
return score;
}
int Game :: getStep(){
return step;
}
void Game :: setHealth(int h){
health=h;
}
void Game :: setMoney(int m){
money=m;
}
void Game :: setScore(int s){
score=s;
}
void Game :: setStep (int s){
step=s;
}
void Game :: distroy_enemy(Enemy e,Cell c){
for (int i=e.index;i<enemyNum-1;i++)
enemys[i]=enemys[i+1];
enemyNum-=1;
c.display();
}
void Game :: distroy_tower(Tower t ,Cell c){
for (int i=t.index;i<towerNum-1;i++)
towers[i]=towers[i+1];
towerNum-=1;
c.display();
}
void Game :: shooting(Tower t){
for(int i=0;i<enemyNum;i++)
{
if (sqrt(pow(enemys[i].cor.first,2)+pow(enemys[i].cor.second,2)) <= t.domain)
enemys[i].health-=t.power;
}
}
void Game :: upgradeTower(Tower t){
t.upgrade();
money-=t.up_cost;
}
void Game :: buyTower(Tower t){
money-=t.price;
towers[towerNum]=t;
towerNum+=1;
t.display();
}
void Game :: sellTower(Tower t ,Cell c){
distroy_tower(t,c);
money+=t.price/2;
}
void Game :: endDisplay(){
End=true;
SDL_FillRect(surface,&surface->clip_rect,SDL_MapRGB(surface->format,0XFF,0XFF,0XFF));
SDL_Surface* text;
font=TTF_OpenFont("AV.TTF",40);
textColor.b=20;
textColor.g=10;
textColor.r=0;
if (health<=0)
{
text=TTF_RenderText_Solid(font ,"You lose" ,textColor);
}
else if (health>0)
{
text=TTF_RenderText_Solid(font ,"Complete the mission" ,textColor);
}
SDL_Rect rect;
rect.x=300;
rect.y=300;
SDL_BlitSurface(text,NULL,surface,&rect);
}
bool Game :: checkEnd(){
if (health<=0 || step==20)
return true;
return false;
}
void Game :: displayMenu(){
SDL_Rect rect;
rect.x=800;
rect.y=0;
SDL_Texture* texture = LoadTexture("menu.png");
SDL_RenderCopy(renderer,texture,NULL,&rect);
}
void Game :: display(Map m){
m.display();
for (int i=0;i<towerNum;i++)
towers[i].display();
for (int i=0;i<enemyNum;i++)
enemys[i].display();
this->displayMenu();
/////////// ttf
}
void Game :: animation(){
SDL_Rect Lrect;
Lrect.x=83;
Lrect.y=0;
SDL_Rect Rrect;
Rrect.x=915;
Rrect.y=0;
SDL_Texture* leftpic = LoadTexture("left.png");
SDL_Texture* rightpic = LoadTexture("right.png");
for (int i=0;i<12;i++)
{
SDL_RenderCopy(renderer,leftpic,NULL,&Lrect);
SDL_RenderCopy(renderer,rightpic,NULL,&Rrect);
Rrect.x-=20;
Lrect.x+=60;
SDL_RendererFlip();
SDL_Delay(300);
}
}
////////////////////////////////////////////////////////////// main //////////////////////////////////////////////////////////////////////
int main()
{
window=SDL_CreateWindow("Frontline Defence",SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,940,600,SDL_WINDOW_SHOWN);
Game game(1000,500);
Map map("map.txt",30);
while ( !game.checkEnd() )
{
if ( SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
return 0;
if (event.type == SDL_MOUSEBUTTONDOWN )
{
SDL_Delay(3000);
}
}
}
game.endDisplay();
return 0;
}
I've done every thing I could but nothing changed!
I've tried including the libraries , typing all parts of the code in the main file and many other ways but it didn't help
These are the errors:
Error 12 error LNK1120: 8 unresolved externals C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\Debug\ConsoleApplication1.exe ConsoleApplication1
Error 4 error LNK2019: unresolved external symbol "public: __thiscall Cell::Cell(void)" (??0Cell##QAE#XZ) referenced in function "public: __thiscall Map::Map(char *,int)" (??0Map##QAE#PADH#Z) C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\classes.obj ConsoleApplication1
Error 8 error LNK2019: unresolved external symbol "public: __thiscall Enemy::~Enemy(void)" (??1Enemy##QAE#XZ) referenced in function "public: __thiscall Game::Game(int,int)" (??0Game##QAE#HH#Z) C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\classes.obj ConsoleApplication1
Error 7 error LNK2019: unresolved external symbol "public: __thiscall Enemy::Enemy(void)" (??0Enemy##QAE#XZ) referenced in function "public: __thiscall Game::Game(int,int)" (??0Game##QAE#HH#Z) C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\classes.obj ConsoleApplication1
Error 10 error LNK2019: unresolved external symbol "public: __thiscall Game::~Game(void)" (??1Game##QAE#XZ) referenced in function "int __cdecl SDL_main(void)" (?SDL_main##YAHXZ) C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\classes.obj ConsoleApplication1
Error 9 error LNK2019: unresolved external symbol "public: __thiscall Map::~Map(void)" (??1Map##QAE#XZ) referenced in function "int __cdecl SDL_main(void)" (?SDL_main##YAHXZ) C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\classes.obj ConsoleApplication1
Error 6 error LNK2019: unresolved external symbol "public: __thiscall Tower::~Tower(void)" (??1Tower##QAE#XZ) referenced in function "public: __thiscall Game::Game(int,int)" (??0Game##QAE#HH#Z) C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\classes.obj ConsoleApplication1
Error 5 error LNK2019: unresolved external symbol "public: __thiscall Tower::Tower(void)" (??0Tower##QAE#XZ) referenced in function "public: __thiscall Game::Game(int,int)" (??0Game##QAE#HH#Z) C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\classes.obj ConsoleApplication1
Error 11 error LNK2019: unresolved external symbol _SDL_main referenced in function _main C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\SDL2main.lib(SDL_windows_main.obj) ConsoleApplication1
You're getting the linker errors referencing constructors and destructors because you haven't provided any implementation for those functions (as Michael Burr pointed out in a comment).
The unresolved external symbol _SDL_main referenced in function _main is because the mainfunction needs to have a specific signature: int main(int argc, char* argv[]) and check that you also have the SDL2main.libin the input to the linker.
Finally, it would seem that you never create any renderer (unless you create somewhere not included in your code example), so you have to add a call to SDL_CreateRenderer() after you create the SDL_Window in main.
I keep getting the same error messages every time on Visual Studio. I don't know where the error is originating. Basically I'm trying to convert an infix expression (A+B-C) to a postfix expression (AB+C-) using stacks. Any help would be greatly appreciated
DriverExpression.cpp
Expression.obj : error LNK2019: unresolved external symbol "public: __thiscall stackType::stackType(int)" (??0?$stackType#D##QAE#H#Z) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix#Expression##QAEXXZ)
Expression.obj : error LNK2019: unresolved external symbol "public: __thiscall stackType::~stackType(void)" (??1?$stackType#D##QAE#XZ) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix#Expression##QAEXXZ)
Expression.obj : error LNK2019: unresolved external symbol "public: char __thiscall stackType::top(void)const " (?top#?$stackType#D##QBEDXZ) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix#Expression##QAEXXZ)
Expression.obj : error LNK2019: unresolved external symbol "public: void __thiscall stackType::initializeStack(void)" (?initializeStack#?$stackType#D##QAEXXZ) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix#Expression##QAEXXZ)
Expression.obj : error LNK2019: unresolved external symbol "public: bool __thiscall stackType::empty(void)const " (?empty#?$stackType#D##QBE_NXZ) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix#Expression##QAEXXZ)
Expression.obj : error LNK2019: unresolved external symbol "public: void __thiscall stackType::push(char)" (?push#?$stackType#D##QAEXD#Z) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix#Expression##QAEXXZ)
Expression.obj : error LNK2019: unresolved external symbol "public: void __thiscall stackType::pop(void)" (?pop#?$stackType#D##QAEXXZ) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix#Expression##QAEXXZ)
C:\Users\Jake Bock\Desktop\CSC 240\Project 7\JBock_Project7\Debug\JBock_Project7.exe : fatal error LNK1120: 7 unresolved externals**
#include <iostream>
#include <fstream>
#include <string>
#include <stack>
#include "Expression.h"
#include "stackType.h"
using namespace std;
int main()
{
string fileName;
string infixExpression, postfixExpression;
Expression expression;
cout << "Converting infix expression to postfix expression\n"
<< "testing infix expressions are in input file\n";
cout << "Enter the input file name ";
cin >> fileName;
ifstream inData;
ofstream outData;
inData.open(fileName.c_str());
outData.open("out.txt");
cout<<"open="<<fileName<<endl; //debugging print
while(inData>>infixExpression)
{
cout<<"Infix="<<infixExpression<<endl; //debugging print
expression.setInfix(infixExpression);
cout<<"setInfix="<<infixExpression<<endl;//debugging print
expression.convertInfixToPostfix();
cout<<"convert="<<infixExpression<<endl; //debugging print
postfixExpression = expression.getPostfix();
cout << "Infix Expression: "
<< infixExpression <<"\n"
<< "Postfix Expression: "
<<postfixExpression<<"\n\n";
outData << "Infix Expression: "
<< infixExpression <<"\n"
<< "Postfix Expression: "
<<postfixExpression<<"\n\n";
}
inData.close();
outData.close();
system("pause");
return 0;
}
================================================================
#ifndef EXPRESSION_H_
#define EXPRESSION_H_
#include "stackType.h"
class Expression
{
private:
std::string infixExpression;
std::string postfixExpression;
bool precedence(char s, char operator2); //ToDo
bool isOperand(char symbol); //ToDo
public:
Expression();
void setInfix(std::string infix);
std::string getInfix();
std::string getPostfix();
void convertInfixToPostfix(); //ToDo
static void convertInfixToPostfix( //ToDo
std::string& infix,
std::string& postfix);
virtual ~Expression();
};
#endif /* EXPRESSION_H_ */
#include <stack>
#include <string>
#include <sstream>
#include "Expression.h"
#include "stackType.h"
#include <iostream>
using namespace std;
Expression::Expression() : infixExpression(""), postfixExpression(""){}
void Expression::setInfix(string infix)
{
infixExpression= infix;
}
string Expression::getInfix()
{
return infixExpression;
}
string Expression::getPostfix()
{
return postfixExpression;
}
void Expression::convertInfixToPostfix()
{
/*Define operator stack*/
stackType<char> s(infixExpression.size());
s.initializeStack();
ostringstream strstream;
int operand = 0;
/*String stream will help us pushing integer to our stream easily.
This is similar to sprintf(), but with less hassles.*/
int size = infixExpression.size();
int iter = 0;
for (; iter < size; ++iter)
{
switch (infixExpression[iter])
{
case '+':
case '-':
case '/':
case '*':
{
if (s.empty())
{
/*We always push the first operator*/
s.push(infixExpression[iter]);
}
else
{
/*if precedence of current operator is higher than
one on top of the stack, we simply push the current
operator to the top of the stack*/
if (precedence(s.top(), infixExpression[iter]))
{
s.push(infixExpression[iter]);
}
else
{
/*Pop from the stack and append it to string stream.
Repeat it unless we find an operator on top of the stack
whose precedence is lower or stack is empty.*/
do
{
strstream << s.top() << ' ';
s.pop();
}while (!s.empty() && !precedence(s.top(), infixExpression[iter]));
/*Now push the current operator to the stack*/
s.push(infixExpression[iter]);
}
}
break;
}
case ' ':
{
break;
}
default:
{
while (iter < size && infixExpression[iter] >= '0' && infixExpression[iter] <= '9')
{
operand = operand * 10 + (infixExpression[iter]-'0');
++iter;
}
strstream << operand << ' ';
operand = 0;
--iter;
break;
}
}
}
/*Pop one by one from operator stack and append it to our stream*/
while(!s.empty())
{
strstream << s.top() << ' ';
s.pop();
}
/*Get the string associated with our string stream*/
postfixExpression = strstream.str();
}
bool Expression::precedence(char s, char operator_specified)
{
if ((operator_specified == '+') || (operator_specified == '-'))
return false;
char top_operator = s;
if ((top_operator == '+') || (top_operator == '-'))
return true;
else
return false;
}
Expression::~Expression()
{
}
//=======================================================================================
#ifndef STACKTYPE_H_
#define STACKTYPE_H_
template <class T>
class stackType
{
private:
int maxStackSize;
int stackTop;
char *list;
void copyStack(const stackType& otherStack);
public:
stackType();
stackType(int stackSize);
~stackType();
char top() const;
void initializeStack();
bool empty() const;
void push(const char newItem);
bool isFullStack() const;
void pop();
const stackType& operator=(const stackType& otherStack);
};
#endif /* stackType_H_ */
#include "stackType.h"
#include <stack>
#include <cassert>
template <class T>
stackType<T>::stackType(){}
template <class T>
stackType<T>::stackType(int stackSize)
{
if (stackSize <= 0)
{
cout << "Size of the array to hold the stack must be positive" << endl;
cout << "Creating an array of size 100" << endl;
maxStackSize = 100;
}
else
maxStackSize = stackSize;
stackTop = 0;
list = new char[maxStackSize];
}
template <class T>
stackType<T>::~stackType()
{
delete [] list;
}
template <class T>
char stackType<T>::top() const
{
assert(stackTop != 0);
return list[stackTop - 1];
}
template <class T>
void stackType<T>::initializeStack()
{
stackTop = 0;
}
template <class T>
bool stackType<T>::empty() const
{
return (stackTop == 0);
}
template <class T>
bool stackType<T>::isFullStack() const
{
return (stackTop == maxStackSize);
}
template <class T>
void stackType<T>::pop()
{
if (!isEmptyStack())
stackTop--;
else
cout << "Cannot remove from an empty stack" << endl;
}
template <class T>
void stackType<T>::push(const char newItem)
{
if (!isFullStack())
{
list[stackTop] = newItem;
stackTop++;
}
else
cout << "Cannot add to a full stack" << endl;
}
template <class T>
void stackType<T>::copyStack(const stackType& otherStack)
{
delete [] list;
maxStackSize = otherStack.maxStackSize;
stackTop = otherStack.stackTop;
}
template <class T>
const stackType<T>& stackType<T>::operator=(const stackType& otherStack)
{
if (this != &otherStack)
copyStack(otherStack);
return *this;
}
unresolved external symbol
Okay, so you've got a linker error here. Whenever you get that, here's the process for fixing it. First, let's look at the error message.
public: __thiscall stackType::stackType(int)" (??0?$stackType#D##QAE#H#Z) referenced in function "public: void __thiscall Expression::convertInfixToPostfix(void)" (?convertInfixToPostfix#Expression##QAEXXZ)
Figure out what method isn't linking. Looking at the error message, it's clearly stackType::stackType(int).
Now what's happening is your method (in this case, a constructor) is declared but never defined. So, go through the checklist...
Is stackType.cpp being included into your build?
Did you remember to write stackType::stackType(int) in your .cpp file?
Are the method signatures for the two functions the same? Did you make one a const method and the other not?
Any weird spelling errors in the class or method name?
Are you doing anything wrong involving templates?
My guess is that #4 is the culprit here, since stackType is a template class. You need to stick all those method definitions into the header and probably aren't.
So the problem turned out being that I needed to keep the template class member function definitions in the header file only. Oy.
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.
I created Linked list and it has no problem and runs. Plus i have to include Binary Tree. and its giving me this error
1> Generating Code...
1> Skipping... (no relevant changes detected)
1> main.cpp
1>main.obj : error LNK2019: unresolved external symbol "public: int __thiscall SDI::BinaryTree::insert(int)" (?insert#BinaryTree#SDI##QAEHH#Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: int __thiscall SDI::BinaryTree::preOrder(void)" (?preOrder#BinaryTree#SDI##QAEHXZ) referenced in function _main
1>C:\Users\Muugii\Documents\Visual Studio 2013\LinkedList\Debug\LinkedList.exe : fatal error LNK1120: 2 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
BinaryTree.h
ifndef SDI_BINARYTREE
define SDI_BINARYTREE
include
namespace SDI
{
class BinaryTree
{
class BTNode
{
public:
int data;
BTNode *left;
BTNode *right;
};
public:
BinaryTree();
~BinaryTree();
int insert(const int value);
int preOrder() const;
int clearTree();
private:
BTNode *headPtr;
int insert(const int value, BTNode *leaf);
int clearTree(BTNode *leaf) const;
int preOrder(BTNode *leaf) const;
};
};
#endif
BinaryTree.cpp
#include"BinaryTree.h"
#include <iostream>
using namespace std;
SDI::BinaryTree::BinaryTree()
{
headPtr = nullptr;
}
SDI::BinaryTree::~BinaryTree()
{
//clearTree(headPtr);
}
int SDI::BinaryTree::insert(const int value, BTNode *leaf)
{
if (value < leaf->data)
{
if (leaf->left != nullptr)
{
insert(value, leaf->left);
}
else
{
leaf->left = new BTNode;
leaf->left->data = value;
leaf->left->left = nullptr;
leaf->left->right = nullptr;
}
}
else if (value >= leaf->data)
{
if (leaf->right != nullptr)
{
insert(value, leaf->right);
}
else
{
leaf->right = new BTNode;
leaf->right->data = value;
leaf->right->left = nullptr;
leaf->right->right = nullptr;
}
}
return 1;
}
Main.cpp
#include <string>
#include <iostream>
#include "Linkedlist.h"
#include "BinaryTree.h"
using namespace std;
int main( int argc, const char *argv[])
{
SDI::LinkedList myList;
//SDI::BinaryTree myTree;
int inp;
....
if (inp2 == 'a')
{
int num;
cout << "\nPlease enter a value to add: ";
cin >> num;
myTree.insert(num);
cout << "\n\t\tValue has been successfully saved\n\n\n";
}
I have tried looking up online, couldn't find any. It would be great help.
As I see you have two functions with name insert. And the first one
int insert(const int value);
was only declared but not defined.
Which part of the error message is unclear to you? It clearly states that you haven't implemented two of your methods:
int SDI::BinaryTree::insert(const int value) {
return 0; // the implementation probably needs some patching up
}
int SDI::BinaryTree::preOrder() const {
return 0; // as does this one
}