I'm trying to implement C++ singleton inside of Xcode project but I'm getting this error:
Redefinition of class
Here is my code (.hpp file):
#ifndef DoingSomething_hpp
#define DoingSomething_hpp
#include <stdio.h>
#endif /* DoingSomething_hpp */
class DoingSomething {
public:
static DoingSomething *instance();
};
This is my .cpp file:
#include "DoingSomething.hpp"
class DoingSomething
{
static DoingSomething *shareInstance;
public:
int doSomething()
{
/*
*/
return 6;
}
static DoingSomething *instance()
{
if (!shareInstance)
shareInstance = new DoingSomething;
return shareInstance;
}
};
On this line (on my cpp file)
class DoingSomething
I'm getting this error:
Redefinition of "DoingSomething".
Any of you knows what I doing wrong or how can fix this error?
I'll really appreciate your help.
You are declaring your class twice in the same translation unit DoingSomething.cpp, i.e. once in the header file you include and again in the cpp-file itself.
Put the class declaration in the header file, and the implementation in the .cpp-file:
Header, i.e. DoingSomething.hpp
#ifndef DoingSomething_hpp
#define DoingSomething_hpp
#include <stdio.h>
class DoingSomething {
public:
int doSomething();
static DoingSomething *instance();
};
#endif /* DoingSomething_hpp */
Implementation, i.e. DoingSomething.cpp
#include "DoingSomething.hpp"
int DoingSomething ::doSomething() {
return 6;
}
DoingSomething *DoingSomething::instance() {
if (!shareInstance)
shareInstance = new DoingSomething;
return shareInstance;
}
Related
I am kind of new to C++ (and StackOverflow). I am trying to get something to work, but I have some #include problems.
I want to call a callback I made (from here), but I am struggling to do this.
This is my code so far. When I include child.hpp in the someclass.hpp file (because it needs information about Child for Callback<Child>), it has a looped include and the compiler crashes.
I have read about forward declarations (would be class Child; in the someclass.hpp file), and after trying I figured out this works, but I also read different opinions about this.
I have all .hpp files guarded with #ifndef CLASSNAME #define CLASSNAME ... #endif
Do I need to change my entire design, or what is the best option in my case?
base.hpp
#include "someclass.hpp"
class Base
{
protected:
unique_ptr<SomeClass> someClass;
};
base.cpp
#include "base.hpp"
Base::Base()
{
this->someClass = make_unique<SomeClass>();
}
child.hpp
#include "base.hpp"
class Child : public Base
{
public:
void callbackFunction(std::string data);
unique_ptr<Callback<Child>> callback;
};
child.cpp
#include "child.hpp"
void Child::callbackFunction(std::string data)
{
/*does something*/
}
Child::Child()
{
this->callback = make_unique<Callback<Child>>(this, &Child::callbackFunction);
//I can call this->callback->call(data); here without problems
this->someClass->setCallback(this->callback);
//^^^^^^^^^^^^^^^ == base.someClass
}
someclass.hpp
#include "child.hpp" // < does crash compiler due to loop
//> someclass.hpp uses child.hpp
//> child.hpp uses base.hpp
//> base.hpp uses someclass.hpp
// and thus loop
class SomeClass
{
public:
void someFunction(std::string data);
void setCallback(unique_ptr<Callback<Child>> callback);
unique_ptr<Callback<Child>> callbackInstance;
};
someclass.cpp
//not 100% sure about the type of this parameter
void setCallback(unique_ptr<Callback<Child>> callback)
{
this->callbackInstance = callback;
}
void SomeClass::someFunction(std::string data)
{
//here I want to call this "Child::callbackFunction" which should go like "this->callbackInstance->call(data)" ?
}
also in someclass.hpp
template<class T>
class Callback
{
public:
Callback(T* instance, void (T::*function)(std::string))
{
this->callbackInstance = instance;
this->callback = function;
}
void call(std::string data)
{
(callbackInstance->*callback)(data);
}
private:
T *callbackInstance;
void (T::*callback)(std::string);
};
To solve the mentioned error("expected class-name before '{' token on child.hpp") you should remove the #include "someclass.hpp" from base.hpp and replace it with a forward declaration for class SomeClass as shown below.
base.hpp
#ifndef BASE_H
#define BASE_H
//NO NEED TO INCLUDE someclass.hpp
#include <memory>
class SomeClass;//FORWARD DECLARE SomeClass
class Base
{
std::unique_ptr<SomeClass> someClass;
public:
//add declaration for default constructor
Base();
};
#endif
base.cpp
#include "base.hpp"
#include "someclass.hpp"
//other things here
Base::Base()
{
this->someClass = std::make_unique<SomeClass>();
}
child.hpp
#ifndef CHILD_H
#define CHILD_H
#include "base.hpp"
#include <memory>
#include "someclass.hpp"
class Child : public Base
{
public:
void callbackFunction(std::string data);
std::unique_ptr<Callback<Child>> callback;
//add declaration for default constrcutor
Child();
};
#endif
child.cpp
#include "child.hpp"
void Child::callbackFunction(std::string data){
/*does something*/
}
Child::Child()
{
this->callback = std::make_unique<Callback<Child>>(this, &Child::callbackFunction);
//I can call this->callback->call(data); here without problems
}
someclass.hpp
#ifndef SOMECLASS_H
#define SOMECLASS_H
#include <string>
//REMOVED include child.hpp from here
class SomeClass
{
public:
void someFunction(std::string data);
//I think I need an instance of Callback<Child> here?
};
template<class T>
class Callback
{
public:
Callback(T* instance, void (T::*function)(std::string))
{
this->callbackInstance = instance;
this->callback = function;
}
void call(std::string data)
{
(callbackInstance->*callback)(data);
}
private:
T *callbackInstance;
void (T::*callback)(std::string);
};
#endif
someclass.cpp
#include "someclass.hpp"
void SomeClass::someFunction(std::string data)
{
//here I want to call this "Child::callbackFunction" which should go like "this->callbackInstance->call(data)" ?
}
The above program compiles and executes successfully as can be seen here.
Summary
Some of the changes that i made are listed below:
Removed unnecessary includes
Added declarations for default constructor in child.hpp and base.hpp
Added include guards in all headers.
I know there are some topics on forward declaration, but after reading them, they don't seem to match this situation. I usually understand what is going on, a full definition is required to allocate. However, I really think I have a full definition here so I'm confused.
//game.h
#include "wizard.h"
#include "warrior.h"
#include "archer.h"
#include "fighter.h"
#ifndef GAME_H
#define GAME_H
enum movetype{
BOOST,
ATTACK,
SPECIAL,
SHIELD
};
struct move{
enum movetype type;
fighter * source;
fighter * target;
};
class game{
public:
game();
~game();
void execmove(move&);
bool trymove();
private:
bool turn;
fighter* t1 [3];
fighter* t2 [3];
};
#endif
So in game I include all the other classes
In fighter I forward declare warrior:
//fighter.h
#ifndef FIGHTER_H
#define FIGHTER_H
class fighter;
class warrior;
struct link {
fighter * warrior;
fighter * target;
};
class fighter{
private:
public:
fighter();
virtual ~fighter();
void action(int, fighter*);
virtual void special(fighter*);
void attack(fighter*);
void defend();
void tick();
void damage(int,int);
void createLink(warrior *);
void removeLink();
protected:
int hp;
int priority;
int boosts;
int shields;
bool alive;
struct link l;
};
#endif
But then when I try to allocate warrior in game:
//game.cpp
#include <iostream>
#include "game.h"
game::game()
{
t1[0] = new warrior();
t1[1] = new wizard();
t1[2] = new archer();
t2[0] = new warrior();
t2[2] = new archer();
t2[1] = new wizard();
}
game::~game()
{
for(int i = 0; i<3; i++)
{
delete t1[i];
delete t2[i];
}
}
void game::execmove(move& m)
{
}
I get:
game.cpp:9:14: error: allocation of incomplete type 'warrior'
t1[0] = new warrior();
^~~~~~~
./fighter.h:7:7: note: forward declaration of 'warrior'
class warrior;
^
game.cpp:13:14: error: allocation of incomplete type 'warrior'
t2[0] = new warrior();
^~~~~~~
./fighter.h:7:7: note: forward declaration of 'warrior'
class warrior;
It seems like that fact that I forward declared makes the compiler ignore the fact that I also included the full definition which is really odd. I'm wondering if there is something that I am missing because I don't know how to fix it if a forward declaration makes the full definition get ignored.
Bottom line: Why can't I allocate warrior since I included the full warrior.h file in game.h?
Here is warrior.h:
#include "fighter.h"
#ifndef FIGHTER_H
#define FIGHTER_H
class warrior{
public:
warrior();
~warrior();
void special(fighter);
private:
};
#endif
Change warrior.h to: (i.e. correct include guards)
#ifndef WARRIOR_H
#define WARRIOR_H
#include "fighter.h"
class warrior{
public:
warrior();
~warrior();
void special(fighter);
private:
};
#endif
Or better still use #pragma once if supported
You need to use different include guard symbols of different .h files.
"fighter.h" defines FIGHTER_H, so when that #if check is encountered in "warrior.h" the definition of the class warrior is skipped.
The incorrectly named guards were making it not include the warrior file. Thank you #1201ProgramAlarm
I have a parametrized class Queue and a subclass ClientsQueue not parametrized that inherits from Queue. I think I have a syntax error:
client.h
#ifndef CLIENT_H_
#define CLIENT_H_
class Client {
public:
Client();
~Client();
};
#endif
queue.h
#ifndef QUEUE_H_
#define QUEUE_H_
template <class T> class Queue {
public:
Queue();
~Queue();
};
#endif
clientsQueue.h
#ifndef CLIENTSQUEUE_H_
#define CLIENTSQUEUE_H_
#include "queue.h"
#include "client.h"
class ClientsQueue: public Queue<Client> {
public:
ClientsQueue();
~ClientsQueue();
};
#endif
clientsQueue.cpp
#include "clientsQueue.h"
ClientsQueue::ClientsQueue() {
};
bank.cpp
#include "clientsQueue.cpp"
int main() {
return 0;
}
So, when I try to compile and run the program, the compiler says:
clientsQueue.cpp:3:1: error: ‘ClientsQueue’ does not name a type
ClientsQueue::ClientsQueue() {
^
I can't see the error. If I quit all the code from clientsQueue.cpp, it works.
How can I fix it?
Thanks!
You should #include "clientsQueue.h" not #include "clientsQueue.cpp" in main file. When you include header you present a declarations to the compiler. You miss the declaration of the class ClientsQueue when you include just the source (cpp) file.
I am creating a simple UTIL.h file contain aplusb(int, int) function for my C++ project. However I cannot compile and the error message is about multiple definition of `aplusb(int, int)'. Would you please help me correct the error or give me some hints?
I attach here my project for your detail reference.
File UTIL.h
#ifndef UTIL_H_
#define UTIL_H_
int aplusb(int a, int b) {
return a + b;
}
#endif /* UTIL_H_ */
File ClassA.h
#ifndef CLASSA_H_
#define CLASSA_H_
class ClassA {
public:
ClassA();
virtual ~ClassA();
private:
int sum;
};
#endif /* CLASSA_H_ */
File ClassA.cpp
#include "ClassA.h"
#include "UTIL.h"
ClassA::ClassA() {
// TODO Auto-generated constructor stub
sum = aplusb(3,5);
}
ClassA::~ClassA() {
// TODO Auto-generated destructor stub
}
File ClassB.h
#ifndef CLASSB_H_
#define CLASSB_H_
class ClassB {
public:
ClassB();
virtual ~ClassB();
private:
int sum;
};
#endif /* CLASSB_H_ */
File ClassB.cpp
#include "ClassB.h"
#include "UTIL.h"
ClassB::ClassB() {
// TODO Auto-generated constructor stub
sum = aplusb(5,6);
}
ClassB::~ClassB() {
// TODO Auto-generated destructor stub
}
Compile error message
ClassB.o: In function `aplusb(int, int)':
/home/vtvan/Desktop/workspace/commonfunc/UTIL.h:11: multiple definition of `aplusb(int, int)'
ClassA.o:/home/vtvan/Desktop/workspace/commonfunc/UTIL.h:11: first defined here
collect2: error: ld returned 1 exit status
make: *** [commonfunc] Error 1
First variant - use inline specifier
#ifndef UTIL_H_
#define UTIL_H_
inline int aplusb(int a, int b) {
return a + b;
}
#endif /* UTIL_H_ */
Second variant - write definition in .cpp file.
You created the function aplusb in your include file. This means that for every file you include it to, a public function aplusb will be created, resulting in a name clash.
If the function should be inline, then mark it so. If the function should be a template, then mark it so. If the function should be as you wrote it, put it in a cpp file and just keep the protoype in the h file.
.h
#ifndef UTIL_H_
#define UTIL_H_
int aplusb(int a, int b);
#endif
.cpp
int aplusb(int a, int b)
{
return a+b;
}
You should declare your aplusb function in the header file, and provide the definition in a cpp file. Something like
util.h:
#ifndef UTIL_H_
#define UTIL_H_
int aplusb(int, int);
#endif /* UTIL_H_ */
The error message is telling you that each time that you include the util.h file, you are re-defining the function, which is exactly what you are doing :-) This is a violation of the ODR (one-definition-rule), which states that the definition (of a function, in this case) must be unique. Otherwise the compiler would be unable to choose between the alternatives (even if, like in this case, they happen to be equal).
Note that templates complicate the matter a bit (in short, because a template is not a definition until instatiated).
Header files are not intended to have actual functions in them (certain C++ aspects such as templates not withstanding). General practice in your case would have you changing your UTIL.H to just prototyping the function (int aplusb(int a, int b);) and moving its implementation to a source file.
You could also make a Util struct where every function is declared static. You can then access every function using Util::<function name>
File UTIL.h
#ifndef UTIL_H_
#define UTIL_H_
struct Util{
static int aplusb(int a, int b) {
return a + b;
}
};
#endif /* UTIL_H_ */
File ClassA.cpp
#include "ClassA.h"
#include "UTIL.h"
ClassA::ClassA() {
sum = Util::aplusb(3,5);
}
ClassA::~ClassA() {
}
File ClassB.cpp
#include "ClassB.h"
#include "UTIL.h"
ClassB::ClassB() {
sum = Util::aplusb(5,6);
}
ClassB::~ClassB() {
}
My code is stored in a main.cpp file which contains the void main() function, and a class MyClass which I now want to split to another file. IDE is Microsoft Visual Studio 2008 Professional.
myclass.h
#include <tchar.h>
class MyClass {
public:
static bool MyFunction (TCHAR* someStringArgument);
};
myclass.cpp
#include <tchar.h>
class MyClass {
private:
static bool someProperty;
static void doSomeOneTimeCode () {
if (!someProperty) {
/* do something */
someProperty = true;
}
}
public:
static bool MyFunction (TCHAR* someStringArgument) {
doSomeOneTimeCode();
/* do something */
return true;
}
};
bool MyClass::someProperty = false;
main.cpp
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include "myclass.h"
void main () {
if (MyClass::MyFunction(TEXT("myString"))) {
_tprintf(TEXT("Yay\n"));
}
}
However, when I try to run it, I get two linker errors.
LNK2019: unresolved external symbol ... (mentions MyClass::MyFunction)
LNK1120: 1 unresolved externals
What can I do to prevent these linker errors?
You declared two classes here. One of them is in myclass.h and the other is in myclass.cpp. Try the following instead:
myclass.h
#ifndef myclass_h_included
#define myclass_h_included
#include <tchar.h>
class MyClass {
private:
static bool someProperty;
static void doSomeOneTimeCode ();
public:
static bool MyFunction (TCHAR* someStringArgument);
};
#endif //!myclass_h_included
myclass.cpp
#include "myclass.h"
/*static*/ bool MyClass::someProperty = false;
void
MyClass::doSomeOneTimeCode() {
//...
}
bool
MyClass::MyFunction(TCHAR* someStringArgument) {
//...
}
Your main.cpp can stay the same. I would pay attention to UncleBens reply as well. One time initialization code should be hidden if at all possible.
Yo can't split a class definition in parts. It must be defined as a whole in one place. If you want to just have some methods of the class defined create a interface class that the MyClass class will later inherit. You should put the class' definition in a header file (myclass.h) and it's implementation in a cpp file (myclass.cpp). That way you can include the "myclass.h" in your main cpp file and use the class in your main function (which should be int main() or int main( int argc, char *argv[] )).
Strange that you didn't get a compiler error, as you are redefining MyClass.
Definitions (implementations) go into the cpp, and they are defined like this:
#include "myclass.h"
//helper functions, particularly if static, don't need to be in the class
//unnamed namespace means this stuff is available only for this source file
namespace
{
bool someProperty;
void doSomeOneTimeCode () {
if (!someProperty) {
/* do something */
someProperty = true;
}
}
}
bool MyClass::MyFunction (TCHAR* someStringArgument) {
doSomeOneTimeCode();
/* do something */
return true;
}