I'm new to C++ and the error codes aren't really compelling to me.
I am trying to build a simple C++ OOP program as a homework assignment but which will gather then display information about book etc.
I am getting an error:
1>Book.obj : error LNK2005: "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Author::getFullName(void)" (?getFullName#Author##QAE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ) already defined in Author.obj
1>Book.obj : error LNK2005: "public: void __thiscall Author::setFirstName(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?setFirstName#Author##QAEXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) already defined in Author.obj
1>Book.obj : error LNK2005: "public: void __thiscall Author::setLastName(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?setLastName#Author##QAEXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) already defined in Author.obj
1>Publisher.obj : error LNK2005: "public: __thiscall Publisher::Publisher(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0Publisher##QAE#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##00#Z) already defined in Book.obj
1>Publisher.obj : error LNK2005: "public: __thiscall Publisher::Publisher(void)" (??0Publisher##QAE#XZ) already defined in Book.obj
1>Publisher.obj : error LNK2005: "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Publisher::getPublisherInfo(void)" (?getPublisherInfo#Publisher##QAE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ) already defined in Book.obj
1>Publisher.obj : error LNK2005: "public: void __thiscall Publisher::setAddress(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?setAddress#Publisher##QAEXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) already defined in Book.obj
1>Publisher.obj : error LNK2005: "public: void __thiscall Publisher::setCity(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?setCity#Publisher##QAEXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) already defined in Book.obj
1>Publisher.obj : error LNK2005: "public: void __thiscall Publisher::setName(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?setName#Publisher##QAEXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) already defined in Book.obj
1>C:\Users\pc\Desktop\School\ITS 340\Labs\Lab 1\Lab 1\Debug\Lab 1.exe : fatal error LNK1169: one or more multiply defined symbols found
Am I missing something here?
Book.cpp
#include <iostream>
using namespace std;
#include "Author.cpp"
#include "Publisher.cpp"
class Book
{
public:
Book();
Book(string title, Author *pAuthor, Publisher *pPublisher, double price);
~Book();
void setTitle(string title);
void setAuthorName(string first, string last);
void setPublisher(string name, string address, string city);
void setPrice(double price);
string convertDoubleToString(double number);
string getBookInfo();
private:
string title;
double price;
Author *pAuthor;
Publisher *pPublisher;
};
Book::Book()
{
}
Book::Book(string title, Author *pAuthor, Publisher *pPublisher, double price)
{
title = title;
price = price;
}
Book::~Book()
{
}
void Book::setTitle(string title)
{
}
void Book::setAuthorName(string first, string last)
{
}
void Book::setPublisher(string name, string address, string city)
{
}
void Book::setPrice(double price)
{
}
string Book::convertDoubleToString(double number)
{
return 0;
}
string Book::getBookInfo()
{
return 0;
}
Publisher.cpp
#include <iostream>
using namespace std;
class Publisher
{
public:
Publisher();
Publisher(string name, string address, string city);
string getPublisherInfo();
void setName(string name);
void setAddress(string address);
void setCity(string city);
private:
string name;
string address;
string city;
};
Publisher::Publisher()
{
}
Publisher::Publisher(string name, string address, string city)
{
name = name;
address = address;
city = city;
}
string Publisher::getPublisherInfo()
{
return "0";
}
void Publisher::setName(string name)
{
name = name;
}
void Publisher::setAddress(string address)
{
address = address;
}
void Publisher::setCity(string city)
{
city = city;
}
You should never include a cpp file in another cpp file or in a header. This almost inevitably leads to duplicate object definitions.
Put declarations into the header file, and definitions into the cpp files. Include headers in cpp files where you need to have access to methods of objects defined in other cpp files.
Take Publisher.cpp as an example: the top part up to and including the }; line need to go into the Publisher.h file. Everything else has to remain in the Publisher.cpp. In addition, you need to add #include Publisher.h to the top of Publisher.cpp, along with other headers that you need to include.
You also need to remove using namespace std; from the header, and use std::string in your declarations. It is OK to put using in your cpp file, though.
Use #IFNDEF to avoid duplicate object definitions if you are really in need to add some cpp to another cpp.
Like
#include <iostream>
using namespace std;
#ifndef CPPADDED
#define CPPADDED
class Publisher
{...}
#endif
In addition to what Dasblinkenlight said,
Your problem is that you did not use ifndef guard. You should use that to avoid this error. A quick search will give you the hint how to add headers.
Create header file example: resource.h and put there prototypes of functions also class.
So it will look like:
#include <iostream>
#include <string>
using namespace std;
class Book
{
public:
Book();
Book(string title, Author *pAuthor, Publisher *pPublisher, double price);
~Book();
void setTitle(string title);
void setAuthorName(string first, string last);
void setPublisher(string name, string address, string city);
void setPrice(double price);
string convertDoubleToString(double number);
string getBookInfo();
private:
string title;
double price;
Author *pAuthor;
Publisher *pPublisher;
};
class Publisher
{
public:
Publisher();
Publisher(string name, string address, string city);
string getPublisherInfo();
void setName(string name);
void setAddress(string address);
void setCity(string city);
private:
string name;
string address;
string city;
};
class Author{
//... prototypes
};
Edit Book.cpp to this:
#include "resource.h"
Book::Book()
{
}
Book::Book(string title, Author *pAuthor, Publisher *pPublisher, double price)
{
title = title;
price = price;
}
Book::~Book()
{
}
void Book::setTitle(string title)
{
}
void Book::setAuthorName(string first, string last)
{
}
void Book::setPublisher(string name, string address, string city)
{
}
void Book::setPrice(double price)
{
}
string Book::convertDoubleToString(double number)
{
return 0;
}
string Book::getBookInfo()
{
return 0;
}
And Publisher.cpp to this:
#include "resource.h"
Publisher::Publisher()
{
}
Publisher::Publisher(string name, string address, string city)
{
name = name;
address = address;
city = city;
}
string Publisher::getPublisherInfo()
{
return "0";
}
void Publisher::setName(string name)
{
name = name;
}
void Publisher::setAddress(string address)
{
address = address;
}
void Publisher::setCity(string city)
{
city = city;
}
And try to do same with Author.cpp,so you put function's prototypes (class) to "resource.h" and include "resource.h" to Author.cpp.
Related
I'm trying to code a little plugin for bakkesmod because I'm pissing myself off.
I watched the only 2 video that exists on this topic but ... it doesn't work and I have this error for each void - >> Severity Code Description Project File Line Suppression State
Error LNK2001 unresolved external symbol "__declspec(dllimport) public: void __thiscall GameWrapper::HookEvent(class std::basic_string<char,struct std::char_traits,class std::allocator >,class std::function<void __cdecl(class std::basic_string<char,struct std::char_traits,class std::allocator >)>)" (_imp?HookEvent#GameWrapper##QAEXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##V?$function#$$A6AXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z#3##Z) TagName C:\Users\leodu\source\repos\TagName\TagName\TrollTagName.obj 1
here is my code.
TroolTagName.cpp (not judge the name)
#include "TrollTagName.h"
BAKKESMOD_PLUGIN(TroolTagName, "Trool Tag Name", "1.0", PERMISSION_ALL)
void TroolTagName::onLoad()
{
this->Log("This is my first Bakkesmod Plugin");
this->LoadHooks();
}
void TroolTagName::onUnload()
{
}
void TroolTagName::LoadHooks()
{
gameWrapper->HookEvent("Function TAGame.GameEvent_Soccar_TA.EventMatchEnded", std::bind(&TroolTagName::GameEndedEvent, this, std::placeholders::_1));
gameWrapper->HookEvent("Function TAGame.AchievementManager_TA.HandleMatchEnded", std::bind(&TroolTagName::GameEndedEvent, this, std::placeholders::_1));
}
void TroolTagName::GameEndedEvent(std::string name)
{
cvarManager->executeCommand("load_freeplay");
}
void TroolTagName::Log(std::string msg)
{
cvarManager->log("TroolTagName: " + msg);
}
TroolTagName.h
#include "bakkesmod\plugin\bakkesmodplugin.h"
#pragma comment(lib, "pluginsdk.lib")
class TroolTagName : public BakkesMod::Plugin::BakkesModPlugin
{
public:
virtual void onLoad();
virtual void onUnload();
void LoadHooks();
void GameEndedEvent(std::string name);
private:
void Log(std::string msg);
};
The project and a Dynamic-library dll project.
I tried adding __declspec (dllexport) before void but ... I got this error - >> redefinition; different linkage and I found nothing for this error so I am blocked :(
I've been working with static for quite a long time but now when the header files come I'm a little confused.
The main problem is this code :
#include <iostream>
#include <string>
#include <sstream>
#include <set>
#ifndef WORD_H
#define WORD_H
#include<unordered_map>
class Word
{
private:
std::string word;
int k;
static std::unordered_map<std::string, int> x;
public:
Word(std::string word) : word(word)
{
if (x.find(word) != x.end())
x.insert({ word , 0 });
else
{
x[word]++;
}
}
std::string getWord() const
{
return x.find(this->word)->first;
}
int getCount() const
{
return x.find(this->word)->second;
}
friend bool operator<(const Word& a, const Word& b);
};
bool operator<(const Word& a, const Word& b)
{
return a.getWord() < b.getWord();
}
#endif
std::ostream& operator<<(std::ostream& out, const Word& w) {
return out << w.getWord() << " " << w.getCount();
}
void printWordCounts(const std::string& line) {
std::istringstream lineIn(line);
std::set<Word> words;
std::string wordStr;
while (lineIn >> wordStr) {
words.insert(Word(wordStr));
}
for (Word w : words) {
std::cout << w << std::endl;
}
}
int main() {
std::string line;
std::getline(std::cin, line);
printWordCounts(line);
std::cout << "---" << std::endl;
std::getline(std::cin, line);
printWordCounts(line);
return 0;
}
I know that there is a problem with the static keyword, but what exactly is it?
Also, the error is one of my favourites. Those errors between linker and STL:
Error LNK2001 unresolved external symbol "private: static class std::unordered_map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int,struct std::hash<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,struct std::equal_to<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,int> > > Word::x" (?x#Word##0V?$unordered_map#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##HU?$hash#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###2#U?$equal_to#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###2#V?$allocator#U?$pair#$$CBV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##H#std###2##std##A) ConsoleApplication63 C:\Users\Ivo\source\repos\ConsoleApplication63\ConsoleApplication63\ConsoleApplication63.obj 1
I hope that someone can give me an explanation.
You have only declared the static member x. You also need to define it outside the class like this:
std::unordered_map<std::string, int> Word::x;
From c++17, you can define x inside the class definition like this:
inline static std::unordered_map<std::string, int> x;
Static variable declarations in classes are identical to declaring a global variable in a header file, except it's 'symbol' lies within the namespace of the class and therefore access to it is protected with visibility levels. This means that like global variable declarations, static class variable declarations have 'weak' linkage and a compilation unit needs to define the symbol definition, so that the linker can tie the memory associated with the variable declarations in other files to exactly one variable.
Defining the static variable is done outside the class like so:
// <variable type> <class type>::<variable name>;
std::unordered_map<std::string, int> Word::x;
Note that only one .cpp file needs to define the variable
1>game.obj : error LNK2001: unresolved external symbol "public: bool __cdecl GameStore::loadFromXml(void)" (?loadFromXml#GameStore##QEAA_NXZ)
1>protocolgame.obj : error LNK2001: unresolved external symbol "public: struct StoreCategory * __cdecl GameStore::getStoreCategoryByName(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?getStoreCategoryByName#GameStore##QEAAPEAUStoreCategory##AEBV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
1>C:\Users\Slavi Dodo\Documents\GitHub\forgottenserver\vc14\x64\Release\theforgottenserver.exe : fatal error LNK1120: 2 unresolved externals
I am so confused! I don't even understand why the error comes.
These is the declaration "gamestore.h"
#ifndef FS_GAMESTORE_H_ADCAA356C0DB44CEBA994A0D678EC92D
#define FS_GAMESTORE_H_ADCAA356C0DB44CEBA994A0D678EC92D
struct StoreOffer {
StoreOffer(uint32_t id, uint32_t thingId, uint8_t addon, uint32_t price, uint8_t type, uint8_t state, std::string name, std::string description, std::vector<std::string> icons)
: id(id), thingId(thingId), addon(addon), price(price), type(type), state(state), name(name), description(description), icons(icons) {}
uint32_t id;
uint32_t thingId;
uint32_t price;
uint8_t type;
uint8_t state;
uint8_t addon;
std::string name;
std::string description;
std::vector<std::string> icons;
};
struct StoreCategory
{
StoreCategory(std::string name, std::string description, std::vector<std::string> icons, std::vector<StoreOffer> offers)
: name(name), description(description), icons(icons), offers(offers) {}
std::string name;
std::string description;
std::string parentCategory;
std::vector<std::string> icons;
std::vector<StoreOffer> offers;
};
class GameStore
{
public:
bool reload();
bool loadFromXml();
StoreOffer* getStoreItemById(uint32_t id);
StoreCategory* getStoreCategoryByName(const std::string& name);
const std::vector<StoreCategory>& getStoreCategories() const {
return storeCategories;
}
bool enabled;
std::vector<StoreCategory> storeCategories;
};
#endif
And this is the definitions "gamestore.cpp"
#include "otpch.h"
#include "gamestore.h"
#include "pugicast.h"
#include "tools.h"
bool GameStore::reload()
{
storeCategories.clear();
return loadFromXml();
}
bool GameStore::loadFromXml()
{
return true;
}
StoreOffer* GameStore::getStoreItemById(uint32_t id) {
for (auto it : storeCategories) {
for (auto item : it.offers) {
if (item.id == id) {
return &item;
}
}
}
return nullptr;
}
StoreCategory* GameStore::getStoreCategoryByName(const std::string& name) {
auto it = std::find_if(storeCategories.begin(), storeCategories.end(), [name](StoreCategory& storeCategory) {
return storeCategory.name == name;
});
return it != storeCategories.end() ? &*it : nullptr;
}
I have read more about the error, but not even found a solution to my situation.
As you see the "loadFromXml" is just returning true, not accepting any arguments as well being public, the problem is very confusing!
Check if gamestore.cpp is being compiled or not!
If not add it to projectname.vcproj in CLCompile list.
When I'm trying to read a file with a function
void readFile(string fileName, string* anArray) {
unsigned int lineCounter = 0;
ifstream inFile = ifstream(fileName);
while (!inFile.eof()) {
string fileLine;
inFile >> fileLine;
if (!fileLine.empty()) {
anArray[lineCounter] = fileLine;
++lineCounter;
}
}
inFile.close();
}
I get the error below, which I assume is because of the pointer on the string array ?
1>Main.obj : error LNK2019: unresolved external symbol "void __cdecl
resource::readFile(class std::basic_string,class std::allocator >,class
std::basic_string,class
std::allocator > *)"
(?readFile#resource##YAXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##PAV23##Z)
referenced in function _main
void readFile(string fileName, string* anArray) {
This is the definition of a member function, but you forgot to write the class name.
void resource::readFile(string fileName, string* anArray) {
As you have it now, you've defined a new function in the global namespace that has nothing to do with resource, so when main tries to use resource::readFile, the definition cannot be found.
So here's my problem. I'm writing web browser plugin in Firebreath. Plugin has to connect to different databases (Firebird, MS SQL, My SQL etc.) depending on client request. So I'm creating class to manage connection to right DB. To connect to Firebird I'm trying to use IBPP. I managed to connect to FB using IBPP in simple test project. But now when I'm doing something much more complex I've got this strange linker error LNK2019.
Exact error message is:
Error 2 error LNK2019: unresolved external symbol "class IBPP::Ptr<class IBPP::IDatabase>
__cdecl IBPP::DatabaseFactory(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)
" (?DatabaseFactory#IBPP##YA?AV?$Ptr#VIDatabase#IBPP###1#ABV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##000000#Z)
referenced in function "class IBPP::Ptr<class IBPP::IDatabase>
__cdecl IBPP::DatabaseFactory(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)"
(?DatabaseFactory#IBPP##YA?AV?$Ptr#VIDatabase#IBPP###1#ABV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##000#Z)
C:\ff-extensions\F4U\build\projects\F4UConv\Connections.obj F4UConv
Code for my connections looks like this:
Header
#ifndef Connections_h
#define Connections_h
#include <cstdarg>
#include <string>
#include "ibpp\ibpp.h"
#include "..\Logger\Logger.h"
using namespace std;
namespace Connections{
class Connection {
public:
void set_logger(Logger::Logger *logger);
virtual bool setup_connection(string machine, string db_path, string login, string passwd)=0;
virtual bool connect()=0;
virtual bool disconnect()=0;
virtual bool setup_statement(string sql_statement, const char *fmt, ...)=0;
template <class Statement>
Statement execute_statement();
protected:
string machine;
string db_path;
string login;
string passwd;
Logger::Logger *logger;
};
class FB_Connection : public Connection {
public:
~FB_Connection();
bool setup_connection(string machine, string db_path, string login, string passwd);
bool connect();
bool disconnect();
bool setup_statement(string sql_statement, const char *fmt, ...);
template <class Statement>
Statement execute_statement();
private:
IBPP::Database db;
};
};
#endif Connections_h
Source
#include "Connections.h"
namespace Connections{
void Connection::set_logger(Logger::Logger *logger){
this->logger = logger;
}
FB_Connection::~FB_Connection(){
if(this->db->Connected()){
this->disconnect();
}
db->Drop();
}
bool FB_Connection::setup_connection(string machine, string db_path, string login, string passwd){
this->machine = machine;
this->db_path = db_path;
this->login = login;
this->passwd = passwd;
try{
this->db = IBPP::DatabaseFactory(this->machine, this->db_path, this->login, this->passwd);
this->db->Create(3);
}catch(IBPP::Exception& e){
if(logger != nullptr){
this->logger->log(Logger::LogMsgValue[Logger::E_LOGMSG_000002]);
this->logger->log(Logger::LEVEL_ERROR, e.ErrorMessage());
}
return false;
}
return true;
}
bool FB_Connection::connect(){
return true;
}
bool FB_Connection::disconnect(){
return true;
}
bool FB_Connection::setup_statement(string sql_statement, const char *fmt, ...){
return true;
}
template <class Statement>
Statement FB_Connection::execute_statement(){
return this;
}
}
I'm googling for two days and still don't know what's the problem. I understand what LNK2019 error means but don't know why it occurs in this case.
The line that generate this error is:
this->db = IBPP::DatabaseFactory(this->machine, this->db_path, this->login, this->passwd);
Can anyone show me what's wrong?
Oh, and I'm using Visual Studio 2012 Express.
You are trying to access the method in the source for which you haven't provided the definition in the connection namespace , i.e
This method :
DatabaseFactory(this->machine, this->db_path, this->login, this->passwd);
Provide a definition for it in the connection namespace.
Write using namespace connections; in the source file.