Can not get the instance of a singleton class from other classes - c++

The problem I am facing is somehow related to "loop inclusion" or "incompleted class"
I have 2 classes:
ControllerManager, this class is declared as Singleton, this class has a object of AuxController.
AuxController, this class has a function that needs to get the instance of ControllerManager
The problem is: when compiling source code, it fails with error "incomplete type" or "invalid type"
Is there any way to fix this problem?
or is there any other way to redesign code structure?
Source code
ControllerManager.h
#ifndef CONTROLLERMANAGER_H
#define CONTROLLERMANAGER_H
#include "auxcontroller.h"
class ControllerManager
{
/* This class is defined as Singleton class */
private:
/* 1. define a private static instance */
static ControllerManager *inst;
public:
/* 2. define a public static accessor */
static ControllerManager *getInstance(){
/* 3. do lazy initialization */
if(!inst){
inst = new ControllerManager();
}
return inst;
}
protected:
/* 4. Define all accessors to be protected */
ControllerManager();
~ControllerManager();
/* property */
private:
int m_code;
public:
int getCode()
{
return m_code;
}
void setCode(int _code)
{
m_code = _code;
}
/* below code causes fail of compilation */
public:
AuxController m_auxcontroller;
};
#endif // CONTROLLERMANAGER_H
ControllerManager.cpp
#include "controllermanager.h"
/* 5. initialize static variable */
ControllerManager *ControllerManager::inst = 0;
ControllerManager::ControllerManager()
{
m_code = 15;
}
ControllerManager::~ControllerManager()
{
delete inst;
}
AuxController.h
#ifndef AUXCONTROLLER_H
#define AUXCONTROLLER_H
/* if do NOT include controllermanager.h with below line,
* and declare ControllerManager class as a forward declaration:
*
* class ControllerManager;
*
* compiler will stop due to "incomplete type"
*/
#include "controllermanager.h"
class AuxController
{
public:
AuxController();
void setControllerCode(int code);
};
#endif // AUXCONTROLLER_H
AuxController.cpp
#include "auxcontroller.h"
AuxController::AuxController()
{
}
void AuxController::setControllerCode(int code)
{
/* if do NOT include controllermanager.h ,
* and declare ControllerManager class as a forward declaration in the header file:
*
* class ControllerManager;
*
* compiler will stop due to "incomplete type" at this line
*
*/
ControllerManager::getInstance()->setCode(code);
}
main.cpp
#include "controllermanager.h"
int main(int argc, char *argv[])
{
ControllerManager *ctlMng = ControllerManager::getInstance();
ctlMng->setCode(10);
return 0;
}

Do not include "controllermanager.h" inside auxcontroller.h, but do include it inside auxcontroller.cpp.
In general you should not include header files by other header files if it can be avoided. Use forward declaration instead. But do include all required header files from cpp files.

The problem consists into a cycle dependency.
In order to solve that problem: use forward declaration and include all needed header only in the cpp (compilation-unit) file.
In ControllerManager.hpp:
class AuxController;
class ControllerManager {
// ...
public: AuxController* m_auxcontroller;
};
// Remember to not use m_auxcontroller in the header file, JUST declaration are allowed.
Note: you have to use pointers or references to the forwarded class, so remember to initialize them correctly.
In the ControllerManager.cpp:
#include "ControllerManager.hpp"
#include "AuxController.hpp" // In Cpp file include everything you need.
// ...
The same in the class AuxController.
In the AuxController.hpp:
// You dont need header of other file in this case.
class AuxController {
// ...
};
In AuxController.cpp:
#include "AuxController.hpp"
#include "ControllerManager.hpp"
// ...

Related

C++ No matching function for call to 'Nodo::Nodo()'

Good morning.
I'm trying to implement a graph in c++ with nodes and edges memorized as lists. I'm italian so: graph/Grafo , edge/Arco , node/Nodo , listEdges/ListaArchi, listNodes/ListaNodi.
This is my code:
Grafo.h
#ifndef GRAFO_H_
#define GRAFO_H_
#include "ListaNodi.h"
class Grafo {
public:
Grafo();
virtual ~Grafo();
void leggiGrafo(std::string nomeFile);
void aggiungiNodo(std::string nomeNodo);
private:
std::string nomeGrafo;
ListaNodi nodi;
};
#endif /* GRAFO_H_ */
Grafo.cpp
#include "Grafo.h"
Grafo::Grafo() {
}
Grafo::~Grafo() {
}
void Grafo::aggiungiNodo(std::string nomeNodo) {
}
void Grafo::leggiGrafo(std::string nomeFile){
}
Arco.h
#ifndef ARCO_H_
#define ARCO_H_
#include <string>
#include "Nodo.h"
class Arco {
public:
Arco();
virtual ~Arco();
Arco *next;
std::string style;
std::string color;
private:
Nodo primo;
Nodo secondo;
};
#endif /* ARCO_H_ */
Arco.cpp (Here is where the problem is:
Arco.cpp:10:12: error: no matching function for call to 'Nodo::Nodo()'
#include "Arco.h"
Arco::Arco() {
// TODO Auto-generated constructor stub
next = NULL;
}
Arco::~Arco() {
// TODO Auto-generated destructor stub
}
Nodo.h
Other problem here:
Nodo.h:15:2: error: extra qualification 'Nodo::' on member 'Nodo' [-fpermissive]
#ifndef NODO_H_
#define NODO_H_
#include <string>
#include "ListaArchi.h"
class Nodo {
public:
Nodo::Nodo(std::string nome);
virtual ~Nodo();
void setColore(std::string colore);
ListaArchi listaArchi;
Nodo *next;
private:
std::string colore;
std::string nome;
std::string label;
};
#endif /* NODO_H_ */
Nodo.cpp
#include "Nodo.h"
#include <string>
Nodo::Nodo(std::string nome) {
this->nome = nome;
this->colore = "white";
next=NULL;
}
Nodo::~Nodo() {
}
Arco.h
Other problem here:
ListaArchi.h:16:2: error: 'Arco' does not name a type
#ifndef LISTAARCHI_H_
#define LISTAARCHI_H_
#include "Arco.h"
class ListaArchi {
public:
ListaArchi();
virtual ~ListaArchi();
Arco arco;
};
#endif /* LISTAARCHI_H_ */
ListaArchi.cpp
#include "ListaArchi.h"
ListaArchi::ListaArchi() {
}
ListaArchi::~ListaArchi() {
}
ListaNodi.h
#ifndef LISTANODI_H_
#define LISTANODI_H_
#include "Nodo.h"
class ListaNodi {
public:
ListaNodi();
virtual ~ListaNodi();
Nodo nodo;
};
#endif /* LISTANODI_H_ */
ListaNodi.cpp
#include "ListaNodi.h"
ListaNodi::ListaNodi() {
nodo = NULL;
}
ListaNodi::~ListaNodi() {
}
Could anyone help me with these problems?
You have multiple problems. One is that in your ListaNodi class use the Nodi class to declare an object nodo. That will use the default constructor of Nodi, but you haven't declared or defined one. Only a constructor taking a string.
The simple solution for the above is to create a Nodi default constructor, i.e. a constructor taking no arguments.
Another problem is in the ListaNodi constructor implementation, where you do
nodo = NULL;
Here you treat nodo as a pointer, which it isn't. The solution to this is to remove that line, and instead use a constructor initializer list:
ListaNodi::ListaNodi()
: nodo{}
{
}
Of course, that requires you to have fixed the first problem above, by creating a default constructor.
Furthermore inside the class definition of Nodo you declare the (non-default) constructor using scoping, which is not needed.
Plain
Nodo(std::string nome);
is all you need.
Finally you have the problem with a circular header-file dependency, where ListaArchi depends on Arco which depends on Nodo which depends on ListaArchi. You need to find a way to break that header-file dependency circle. The simplest way to break such a circle is to use pointers somewhere, and forward declaration of the type instead of including the header file.
It seems that you are making lists, which means you can very easily break the header-file circular dependency by making the "nodes" in the list classes being pointers, something which they probably should be from the beginning. That will actually solve the two first problems I mentioned as well.
Then the ListaArchi.h header file could look like this:
#ifndef LISTAARCHI_H_
#define LISTAARCHI_H_
class Arco; // Forward declaration instead of header file inclusion
class ListaArchi {
public:
ListaArchi();
virtual ~ListaArchi();
Arco* arco; // Declares as a pointer
};
#endif /* LISTAARCHI_H_ */
And ListaNode.h should look like
#ifndef LISTANODI_H_
#define LISTANODI_H_
class Nodo; // Forward declaration instead of header file inclusion
class ListaNodi {
public:
ListaNodi();
virtual ~ListaNodi();
Nodo* nodo; // Declare as a pointer
};
#endif /* LISTANODI_H_ */
Finally your ListaNodi constructor makes more sense with the NULL assignment, but I suggest you still use construction initializer lists:
ListaNodi::ListaNodi()
: nodo{nullptr}
{
}

C++ Can a class pass itself by reference?

Trying to pass a parent class object to a child class object so that the child class object has control over the parent class object's methods.
This is however resulting in header related issues.
I've tried forward declaring one of the classes but it seems whatever class is declared first always has trouble reading from the class declared below.
Both errors refer to Device' constructor where try to call dm's hello world method, they are:
Use of undefined type 'DeviceManager'
Left of '->HelloWorld' must point to class/struct/union/generic type
...
//main.cpp
#include "parent.h"
void main()
{
cout << "Created DeviceManager\n";
DeviceManager* deviceManager = 0;
deviceManager = new DeviceManager;
cout << "Giving DeviceManager a device\n";
deviceManager->p = new Device(deviceManager);
cout << "Giving Device a reference to DevicenManager\n";
deviceManager->Share();
}
...
class DeviceManager;
class Device
{
public:
Device(DeviceManager* manager)
{
dm = 0;
this->dm = manager;
this->dm->HelloWorld();
}
DeviceManager* dm;
};
//device manager
class DeviceManager
{
public:
DeviceManager()
{
p = 0;
}
void HelloWorld()
{
//if this calls we know the child has control over the parent.
cout << "Hello World";
}
Device* p;
};
Yes.
To solve circular dependencies with class member and function declarations, you can forward-declare a class:
class A;
class B {
A *a;
};
class A {
B *b;
};
To define class member functions that access members of the other class, you must define the function after the other class has been defined:
class B;
class A {
public:
void f(B &arg);
};
class B {
public:
void g(A &arg);
};
void A::f(B &arg) {
arg.g(*this);
}
void B::g(A &arg) {
arg.f(*this);
}
Usually, in a C++ project, you wouldn't even encounter this problem: You would put function definitions, i.e. implementations, into .cpp files, while putting the class definitions into header files. Class forward declarations, if neccesary, could be put into their own header files that are included by all headers that need them.
A full example of how you would split the above code into multiple files:
a.cpp
#include "a.h"
#include "b.h"
void A::f(B &arg) {
arg.g(*this);
}
b.cpp
#include "b.h"
#include "a.h"
void B::g(A &arg) {
arg.f(*this);
}
a.h
#ifndef _A_H_
#define _A_H_
#include "forward_declarations.h"
class A {
public:
void f(B &arg);
};
#endif //_A_H_
b.h
#ifndef _B_H_
#define _B_H_
#include "forward_declarations.h"
class B {
public:
void g(A &arg);
};
#endif //_B_H_
forward_declarations.h
#ifndef _FORWARD_DECLARATIONS_H_
#define _FORWARD_DECLARATIONS_H_
class A;
class B;
#endif //_FORWARD_DECLARATIONS_H_
As a general rule of thumb, if you need to forward-declare a class, you might have misdesigned something and should think about whether there is a better way (but there also are perfectly valid use cases that require class forward declarations).
If you don't understand my #ifndef, #define and #endif preprocessor lines: These are header guards, and should be used with all files that are included somewhere else, exception you know precisely what you're doing. Believe me. You'll regret ommiting one.
If your problem is cyclic dependancy, like this:
// DeviceManager.h
#include "device.h"
class DeviceManager
{
DeviceManager(Device& device) {}
};
// Device.h
#include "DeviceManager.h"
class Device
{
Device(DeviceManager& manager) {}
};
You can solve the problem be forward declaring one of the classes, and passing the object by pointer.
// Device.h
//#include "DeviceManager.h"
class DeviceManager;
class Device
{
Device(DeviceManager* manager) {}
};

How I can auto increment each class objects?

I have a class that contain two private int , one is const (m_id) and the other one is static (next_id).
I want to set m_id to next_id and increment next_id each time I create an object of the class.
But since it's a const I can't set it like that :
Class::Class()
{
m_id = next_id++;
}
I need to set it like that
Class::Class() :m_id(next_id)
{
next_id++;
}
But that's not good either because I can't access private static like that.
Someone told me that const is not intented to be used for that, so to simply remove it. Is that really the only solution?
edit : here the full header and source
header
#ifndef ENTITY_H_LEA12OED
#define ENTITY_H_LEA12OED
#include "EntityKey.h"
#include "ComponentManager.h"
class Entity
{
public:
Entity ();
virtual ~Entity ();
private:
ekey m_key;
ComponentManager m_componentManager;
const int m_id;
static int next_id;
};
#endif /* end of include guard: ENTITY_H_LEA12OED */
source
#include "Entity.h"
Entity::Entity() :m_id(next_id++)
{
}
Entity::~Entity()
{
}
(of course EntityKey and ComponentManager doesn't have anything to do with my question)
(edit 2: corrected some errors in the code due to testing)
You need to define next_id, or else it will compile, but not link. Like so:
class Class
{
/* whatever */
};
Class::Class() :m_id(next_id++)
{
/* whatever */
}
int Class::next_id = 0;

Inclusion problem

I have an inclusion pattern as follows:
/*
* Class1.h
*/
#ifndef CLASS1_H_
#define CLASS1_H_
#include "Class2.h"
namespace Class1_namespace
{
class Class1
{
Class2* Class2_ptr;
void Class1_member()
{
(*Class2_ptr).Class2_method();
}
};
}
#endif /* CLASS1_H_ */
/*
* Class2.h
*/
#ifndef CLASS2_H_
#define CLASS2_H_
#include "Class1.h"
class Class2
{
Class1_namespace::Class1 Class2_data;
public:
void Class2_method(){};
};
#endif /* CLASS2_H_ */
/*
* main.cpp
*/
#include "Class1.h"
int main()
{
return 0;
}
However, this leads to the error “'Class1_namespace' does not name a type.”
Is this error caused by the ordering of my inclusions?
What are some possible solutions? I'm dubious about forward declarations solving my problem.
Class1 doesn't need to include Class2.
When you have mutual dependency (which you don't -- you could just not include 2 in 1), you can usually solve it by using forward declarations instead of inclusions.
For example, let's say that Class1 looked like this
#include "Class2.h"
namespace Class1_namespace
{
class Class1
{
Class2* class2;
};
}
Where you think you need the include, you could instead do this:
class Class2;
namespace Class1_namespace
{
class Class1
{
Class2* class2;
};
}
to break the mutual inclusion.
In class1.h, try removing the unnecessary and circular #include of class2.h. If a circular dependency is required -- or even if not -- consider using forward declarations.

What is the error in the following g++ class construction?

I receive a g++ error (undefined reference to 'SomeClass::SomeClass(int)' and 'SomeClass::~SomeClass') with the following:
/*
* SomeClass.h
*
*/
#ifndef SOMECLASS_H_
#define SOMECLASS_H_
class SomeClass
{
public:
SomeClass();
SomeClass(int someInt);
~SomeClass();
};
#endif /* SOMECLASS_H_ */
/*
* SomeClass.cpp
*
*/
#include "SomeClass.h"
SomeClass::SomeClass()
{
}
SomeClass::SomeClass(int someInt)
{
}
SomeClass::~SomeClass()
{
}
/*
* main.cpp
*
*/
#include "SomeClass.h"
int main()
{
SomeClass::SomeClass someObject(1);
return 0;
}
SomeClass::SomeClass someObject(1);
First of all that's not valid, because SomeClass::SomeClass names the constructor, and not the class type. Just say SomeClass. Then you probably forget to link against SomeClass.cpp's object file. Be sure to include it in the compiler command line when you compile the executable, or add it to the project config by whatever IDE you are using.
SomeClass isn't in a namespace.
SomeClass someObject(1);