C++ class redefinition error - c++

I am compiling a logging program, but I am receiving this error and cant figure it out for the life of me...
logger.cpp:15: error: redefinition of ‘class Logger’
logger.h:20: error: previous definition of ‘class Logger’
with gcc when i compile with
g++ -Wall logger.cpp -o log
logger.h:
#ifndef LOGGER_H
#define LOGGER_H
#include <fstream>
#include <iostream>
#include <string>
using std::string;
class Logger
{
static Logger* m_pInstance;
public:
static Logger* Instance() { return m_pInstance; }
void writeLog(string message);
void openLogFile(string fileName);
void closeLogFile();
void deleteLogger();
};
#endif
logger.cpp
#include "logger.h"
#include <fstream>
#include <iostream>
class Logger
{
static Logger* m_pInstance;
std::ofstream m_pOutputFile;
Logger()
{
}
~Logger()
{
}
public:
static Logger* Instance()
{
if(!m_pInstance)
{
m_pInstance = new Logger;
}
return m_pInstance;
}
void writeLog(std::string message)
{
m_pOutputFile << message << "\n";
std::cout << "you just wrote " << message << " to the log file!\n" << std::endl;
}
void openLogFile(std::string fileName)
{
m_pOutputFile.open(fileName.c_str(),std::ios::out);
}
void closeLogFile()
{
m_pOutputFile.close();
}
void deleteLogger()
{
delete m_pInstance;
}
};
Logger* Logger::m_pInstance = NULL;

It's exactly what the error message says. The implementation file can't just provide a redefinition of the class adding new member variables and conflicting function bodies wherever it pleases. Instead, provide definitions for the functions and static member variables you've already declared.
#include "logger.h"
#include <fstream>
#include <iostream>
static Logger::Logger* m_pInstance;
Logger::Logger()
{
}
Logger::~Logger()
{
}
// this also is illegal, there's a body provided in the header file
//Logger* Logger::Instance()
//{
// if(!m_pInstance)
// {
// m_pInstance = new Logger;
// }
// return m_pInstance;
//}
void Logger::writeLog(std::string message)
{
m_pOutputFile << message << "\n";
std::cout << "you just wrote " << message << " to the log file!\n" << std::endl;
}
and so on

Well, because you are redefining the class. You can't say 'class Logger {' again in the .cpp when you already included it from the .h.

Compiler always expects only one class definition in the whole namespace(or scope) that class belongs to. Currently in the code you specified, you would see that there are infact 2 class definitions: one in .h file and another one in .cpp file. That is why the compiler is complaining that you are redefining a class which is not allowed.
Generally whenever you encounter a compiler error, it's a good idea to look at the lines that compiler tells. Most of the time the problem is in the line the compiler points out.

Related

C++ compiling error

I have a compiling error in C++ using classes. I have worked with classes before and have never encountered this error. I have tried adding static before the method ImprtData but that only prompted more errors.
error: invalid use of non-static member function bank.ImprtData;
here is my .cpp
#include "componets.h"
User::User() {
std::cout << "loaded" << std::endl;
}
void User::ImprtData() {
std::cout << "loaded.\n";
}
and here is my .h
#include <sstream>
#include <fstream>
#include <vector>
#include <iostream>
#include <string>
class User {
public:
User();
void write();
void launch_main_menu();
void login();
void ImprtData();
private:
void deposit();
void withdrawl();
std::string account_name;
int account_pin;
float account_balance;
std::string account_user_name;
};
and finally my main
#include "componets.h"
int main() {
std::cout << "Welcome to Bank 111.\n";
User bank;
bank.ImprtData;
return 0;
}
This is essentially a simple typo. Replace
bank.ImprtData;
with
bank.ImprtData();
to call the function. The expression bank.ImprtData is confusing the compiler since it's interpreting it as the address of a function, and issues a diagnostic since the function is not static.
bank.ImprtData; should be bank.ImprtData();

Cannot create a method in a class

I am new to c++ but have had some experience with java. I am trying to create a class but when i attempt to make a new method in the class I get several error (this is my .cpp file)
//.cpp file
#include "Test.h"
#include "Test.h"
#include <iostream>//unresolved inclusion
using namespace std;
void speak() {
if (happy) {//Symbol hapy could not be resolved
cout << "Meouw!" << endl;
} else {
cout << "Ssssss!" << endl;
}
}
void Test::makeHappy() { // member decleration not found
happy = true;//Symbol hapy could not be resolved
}
void Test::makeSad() { // member decleration not found
happy = false;//Symbol hapy could not be resolved
}
I dont get any errors in my heder file but have included it just in case
#ifndef TEST_H_
#define TEST_H_
class Test {
private:
bool happy;
public:
void makeHappy();
void makeSad();
void speak();
};
#endif /* TEST_H_ */
Finally I have another .cpp file I use which also gets errors
#include <iostream>//unresolved inclusion
#include "Test.h"
#include "Test.cpp"
using namespace std;
int main() {
Test jim;
jim.makeHappy();//method make happy could not be resolved
jim.speak();//method speak could not be resolved
Test bob;
bob.makeSad();//method make happy could not be resolved
bob.speak();//method speak could not be resolved
return 0;
}
This is the new error message I get when compiling
<!-- begin snippet: js hide: false -->
Sorry if this question is to open ended but I just cannot seem to find answers elsewhere.
this is your header file Test.h:
happy member was named bhappy_
for a private member think to add a getter and setter public member functions
#ifndef TEST_H_
#define TEST_H_
class Test {
private:
bool bhappy_;
public:
Test() // ctor
virtual ~Test() // dtor
public:
void makeHappy();
void makeSad();
void speak();
};
#endif /* TEST_H_ */
this is your Test.cpp file:
It's not advised to use using namespace std;
Don't include your header two times
//.cpp file
#include "Test.h"
#include <iostream>//unresolved inclusion
//ctor
Test::Test() : bhappy_(false)
{}
Test::~Test(){}
void Test::speak() {
if (bhappy_) {//Symbol hapy could not be resolved
std::cout << "Meouw!" << endl;
} else {
std::cout << "Ssssss!" << endl;
}
}
void Test::makeHappy() {
bhappy_ = true;//Symbol hapy could not be resolved
}
void Test::makeSad() { // member decleration not found
bhappy_ = false;//Symbol hapy could not be resolved
}
This is your main function:
#include "Test.h"
int main(int argc, char** argv) {
Test jim;
jim.makeHappy();//method make happy could not be resolved
jim.speak();//method speak could not be resolved
Test bob;
bob.makeSad();//method make happy could not be resolved
bob.speak();//method speak could not be resolved
return 0;
}
You need specify Test::speak().
Take should use this. to use class attribut. Think about getter and setter.
And finally, look C++ training, it should be usefull ^^ .
See you.

How to correctly extend a class in C++ and writing its header file?

I've got a third party library named person.lib and its header person.h. This is my actual project structure and it compiles and runs perfectly.
Actual Structure:
main.cpp
#include <iostream>
#include <time.h>
#include <ctype.h>
#include <string>
#include "person.h"
using namespace person;
using namespace std;
class Client : public Person
{
public:
Client();
void onMessage(const char * const);
private:
void gen_random(char*, const int);
};
Client::Client() {
char str[11];
gen_random(str, 10);
this->setName(str);
}
void Client::onMessage(const char * const message) throw(Exception &)
{
cout << message << endl;
}
void Client::gen_random(char *s, const int len) {
//THIS FUNCTION GENERATES A RANDOM NAME WITH SPECIFIED LENGTH FOR THE CLIENT
}
int main()
{
try
{
Person *p = new Client;
p->sayHello();
}
catch(Exception &e)
{
cout << e.what() << endl;
return 1;
}
return 0;
}
I want to refactor my code by dividing the declaration of my Client class from its definition and create client.h and client.cpp. PAY ATTENTION: sayHello() and onMessage(const * char const) are functions of the person library.
Refactored Structure:
main.cpp
#include <iostream>
#include "client.h"
using namespace person;
using namespace std;
int main()
{
try
{
Person *p = new Client;
p->sayHello();
}
catch(Exception &e)
{
cout << e.what() << endl;
return 1;
}
return 0;
}
client.cpp
#include "client.h"
using namespace person;
using namespace std;
Client::Client() {
char str[11];
gen_random(str, 10);
this->setName(str);
}
void Client::onMessage(const char * const message) throw(Exception &)
{
cout << message << endl;
}
void Client::gen_random(char *s, const int len) {
//THIS FUNCTION GENERATES A RANDOM NAME WITH SPECIFIED LENGTH FOR THE CLIENT
}
client.h
#ifndef CLIENT_H
#define CLIENT_H
#include <time.h>
#include <ctype.h>
#include <string>
#include "person.h"
class Client : public Person
{
public:
Client();
void onMessage(const char * const);
private:
void gen_random(char*, const int);
};
#endif
As you can see, I've simply created a client.h in which there's the inclusion of the base class person.h, then I've created client.cpp in which there's the inclusion of client.h and the definitions of its functions. Now, the compilation gives me these errors:
error C2504: 'Person': base class undefined client.h 7 1 Test
error C2440: 'inizialization': unable to convert from 'Client *' to 'person::impl::Person *' main.cpp 15 1 Test
error C2504: 'Person': base class undefined client.h 7 1 Test
error C2039: 'setName': is not a member of 'Client' client.cpp 8 1 Test
error C3861: 'sendMessage': identifier not found client.cpp 34 1 Test
It's a merely cut&copy refactoring but it doesn't work and I really don't understand WHY! What's the solution and why it gives me these errors? Is there something about C++ structure that I'm missing?
Here's a dog-n-bird implementation (ruff ruff, cheep cheep)
cLawyer is defined and implemented in main.cpp, while cPerson and cClient are defined in their own header files, implemented in their own cpp file.
A better approach would store the name of the class. Then, one wouldn't need to overload the speak method - one could simply set the className in each derived copy. But that would have provided in my estimates, a less useful example for you.
main.cpp
#include <cstdio>
#include "cClient.h"
class cLawyer : public cPerson
{
public:
cLawyer() : cPerson() {}
~cLawyer() {}
void talk(char *sayWhat){printf("cLawyer says: '%s'\n", sayWhat);}
};
int main()
{
cPerson newPerson;
cClient newClient;
cLawyer newLawyer;
newPerson.talk("Hello world!");
newClient.talk("Hello world!");
newLawyer.talk("Hello $$$");
return 0;
}
cPerson.h
#ifndef cPerson_h_
#define cPerson_h_
class cPerson
{
public:
cPerson();
virtual ~cPerson();
virtual void talk(char *sayWhat);
protected:
private:
};
#endif // cPerson_h_
cPerson.cpp
#include "cPerson.h"
#include <cstdio>
cPerson::cPerson()
{
//ctor
}
cPerson::~cPerson()
{
//dtor
}
void cPerson::talk(char *sayWhat)
{
printf("cPerson says: '%s'\n",sayWhat);
}
cClient.h
#ifndef cClient_h_
#define cClient_h_
#include "cPerson.h"
class cClient : public cPerson
{
public:
cClient();
virtual ~cClient();
void talk(char *sayWhat);
protected:
private:
};
#endif // cClient_h_
cClient.cpp
#include "cClient.h"
#include <cstdio>
cClient::cClient()
{
//ctor
}
cClient::~cClient()
{
//dtor
}
Output
cPerson says: 'Hello world!'
cClient says: 'Hello world!'
cLawyer says: 'Hello $$$'
Suggestions noted above:
//In the cPerson class, a var
char *m_className;
//In the cPerson::cPerson constructer, set the var
m_className = "cPerson";
//Re-jig the cPerson::speak method
void cPerson::speak(char *sayWhat)
{
printf("%s says: '%s'\n", m_className, sayWhat);
}
// EDIT: *** remove the speak methods from the cClient and cLawyer classes ***
//Initialize the clas name apporpriately in derived classes
//cClient::cClient
m_className = "cClient";
//Initialize the clas name apporpriately in derived classes
//cLaywer::cLaywer
m_className = "cLawyer";
You are declaring the class Client twice - once in the .h file and once in .cpp. You only need to declare it in the .h file.
You also need to put the using namespace person; to the .h file.
If class Person is in namcespace person, use the person::Person to access it.
The client.cpp must contain definitions only!
I think for the linker the class Client defined in client.h and class Client defined in client.cpp are different classes, thus it cannot find the implementation of Client::Client(). I purpose to remove the declaration of class Client from the client.cpp and leave there only definitions of functions:
// client.cpp
#include <time.h>
#include <ctype.h>
#include <string>
#include "client.h"
using namespace std;
Client::Client()
{
//DO STUFF
}
void Client::onMessage(const char * const message)
{
//DO STUFF
}
void Client::gen_random(char *s, const int len) {
//DO STUFF
}

How to use header files for classes?

I'm having trouble creating an OOP version of Hello World. How would I add the World object definition to my header?
Main.cpp:
#include "stdafx.h"
#include "World.h"
#include <iostream>
int main() {
World world;
World world2(5);
std::cin.get();
return 0;
}
World.cpp:
#include "stdafx.h"
#include <iostream>
class World {
public:
World() {
std::cout << "Hello World!" << std::endl;
}
World(int test) {
std::cout << "Hello World!" << std::endl;
}
~World() {
std::cout << "Good Bye!" << std::endl;
}
};
World.h:
class World;
class World(int);
Errors:
1>d:\programming\c++\consoleapplication1\consoleapplication1\world.h(2): error C2062: type 'int' unexpected
1>d:\programming\c++\consoleapplication1\consoleapplication1\main.cpp(6): error C2079: 'world' uses undefined class 'World'
1>d:\programming\c++\consoleapplication1\consoleapplication1\main.cpp(7): error C2079: 'world2' uses undefined class 'World'
Define your class in the header file. You should also definitely use an include guard, to avoid problems when several other files include the same header (not a problem with your current example, but still, it's a very good practice):
// This is the include guard.
#ifndef WORLD_H
#define WORLD_H
class World {
public:
World();
World(int test);
~World();
};
#endif
And define the member functions of that class in the cpp file:
#include "World.h"
#include <iostream>
World::World()
{
std::cout << "Hello World!" << std::endl;
}
World::World(int test)
{
std::cout << "Hello World!" << std::endl;
}
World::~World()
{
std::cout << "Good Bye!" << std::endl;
}
However, you can also define both the class as well the member functions directly in the header file, if you so wish. In that case, you do not need a .cpp file for your class at all. In order to do that, just delete your current World.h header and rename World.cpp to World.h (and add the include guard, as recommended previously.)
Finally, there's a third way you can do this, which also only needs a header file and no .cpp file, where you define the member functions inside the header, but after the class definition by making use if the inline keyword:
#ifndef WORLD_H
#define WORLD_H
#include <iostream>
class World {
public:
World();
World(int test);
~World();
};
inline World::World()
{
std::cout << "Hello World!" << std::endl;
}
inline World::World(int test)
{
std::cout << "Hello World!" << std::endl;
}
inline World::~World()
{
std::cout << "Good Bye!" << std::endl;
}
#endif
This is useful when you don't want the interface of your class to be difficult to read, but still want to be able to do without a .cpp file. Note, however, that not using a .cpp file can increase compilation times when you build a project that includes the header in several different files, and will also trigger a rebuild of all those files if you make even the slightest change in the implementations of the member functions in that header file. Because of this, having a .cpp file for each class is a good idea most of the time, since you can edit that freely without it triggering a rebuild of every other source file that includes the header.
Your header should look like this
#ifndef CLASS_World
#define CLASS_World
class World
{
private:
int m_nValue;
public:
World()
int World(int value)
#endif

Reference C++ struct object in another file?

I'm in the process of trying to make a game-in-progress more modular. I'd like to be able to declare a single array of all the room_t objects in the game (room_t rooms[]), store it in world.cpp and call it from other files.
The truncated code below does not work, but it's as far as I've gotten. I think I need to use extern but have not been able to find a method that works correctly. If I try and declare the array in the header file, I get a duplicate object error (as each file calls world.h, I'd assume).
main.cpp
#include <iostream>
#include "world.h"
int main()
{
int currentLocation = 0;
cout << "Room: " << rooms[currentLocation].name << "\n";
// error: 'rooms' was not declared in this scope
cout << rooms[currentLocation].desc << "\n";
return 0;
}
world.h
#ifndef WORLD_H
#define WORLD_H
#include <string>
const int ROOM_EXIT_LIST = 10;
const int ROOM_INVENTORY_SIZE = 10;
struct room_t
{
std::string name;
std::string desc;
int exits[ROOM_EXIT_LIST];
int inventory[ROOM_INVENTORY_SIZE];
};
#endif
world.cpp
#include "world.h"
room_t rooms[] = {
{"Bedroom", "There is a bed in here.", {-1,1,2,-1} },
{"Kitchen", "Knives! Knives everywhere!", {0,-1,3,-1} },
{"Hallway North", "A long corridor.",{-1,-1,-1,0} },
{"Hallway South", "A long corridor.",{-1,-1,-1,1} }
};
Just add extern room_t rooms[]; in your world.h file.
world.h
extern room_t rooms[];
The problem is that you're trying to reference a variable you've declared in the .cpp file. There's no handle on this outside of the scope of this file. In order to fix this, why not declare the variable in the .h file but have an Init function:
room_t rooms[];
void Init();
Then in the .cpp
void Init() {
// create a room_t and copy it over
}