Global class in c++ - c++

In my project I have a class named globalClass which kepts global variables for each classes and their created instances.
The aim of this globalClass to send all other classes and their created instances the same value for its each variable. If one class's instance change that value, the others(including main.cpp) must see the new value.
Think that,
I have a int variable named foo and defined as public and a value of 100 at globalClass.h;
class globalClass
{
public:
int foo = 100;
}
I have a another classes named class2nd,class3rd,class4th
I have intances of class2nd,class3rd and class4th defined like (in main.cpp)
#include "class2nd.h"
#include "class3rd.h"
#include "class4th.h"
class2nd class2ndA;
class2nd class2ndB;
class2nd class2ndC;
class3rd class3rdA;
class3rd class3rdB;
class3rd class3rdC;
class4th class4thA;
class4th class4thB;
class4th class4thC;
I can reach the foo of globalClass from any of the other classes like
(eg. class2nd)
#include "globalClass.h"
globalClass glb;
void globalClass::someFunction()
{
glb.foo = 123;
}
Now I have to see the foo as 123 from all other class but I see it as 100 as defined on globalClass.h. It can only be seen as 123 on class2nd.
What do I have to do to see the foo as unique from all classes and their instances.... ?

One solution would be to use a Singleton for your global class. You can see for example this answer.
The problem here is that you are defining on class per compilation units (ie per .cpp file you compile) which means that would have effectively a different instance of your class in each of your cpp files.
You should also think about using the Singleton Design Pattern as it is rarely a good design to adopt when building an application. You can see this to understand more about its use cases!

As Thomas Caissard told, the solution is Singleton Pattern.
Here is how for anyone who is looking for solution rather than me...
Singleton.h
#ifndef Singleton_H
#define Singleton_H
class Singleton
{
private:
Singleton();
~Singleton();
static bool isInit;
public:
static Singleton* getInstance();
int foo;
};
#endif
Singleton.cpp
#include "Singleton.h"
bool Singleton::isInit=false;
Singleton* Singleton::getInstance()
{
static Singleton s;
return isInit? &s:0;
}
Singleton::Singleton()
{
isInit=true;
}
Singleton::~Singleton()
{
isInit=false;
}
main.cpp( or otherClass with same syntax )
#include "Singleton.h"
void main() {
Singleton* p = Singleton::getInstance();
p->foo = 123; // Use variable from everywhere with same value....
// Other staffs
}

Related

Multiple accesses of a singleton object in many classes

I have a struct that multiple classes can access and edit. So I created this struct's object as static in class and created a get method.
In Class1.cpp:
#include "Class1.h"
static MyStruct struct;
MyStruct* Class1::get_my_struct()
{
return &struct;
}
I thought of creating this class`s object as a singleton to guarantee that this struct can be accessed through a single object.
In Class2.cpp:
#include "Class2.h" //Class1.h file included in this file.
void Class2::log_value()
{
Class1& singleton_obj_cls1 = Class1::getObject(): //return singleton object
singleton_obj_cls1 .get_my_struct().tempr_val=log_temp_val(); //log this value of struct by class 2 method
}
void Class2::change_value()
{
Class1& singleton_obj_cls1 = Class1::getObject():
//Do I have to get the singleton object for different methods even though they are in the same class?
//Can a singleton object get in one place in class and the whole class use it as a class member?
singleton_obj_cls1 .get_my_struct().tempr_val=45;
singleton_obj_cls1 .get_my_struct().x_val=66 ;
}
I have class 3 class that uses both class1 and class 2.By the way, I changed class2`constructor to a singleton.
In Class3.cpp:
#include "Class3.h" //Both Class1.h and Class2.h file included in this file.
void Class3::calculate_value()
{
Class1& singleton_obj_cls1 = Class1::getObject():
Class2& singleton_obj_cls2 = Class2::getObject():
singleton_obj_cls2.log_value();
singleton_obj_cls1.get_my_struct().pressure_value=300;
}
My third question is, Is there a better design method that you can fix instead of getting singleton objects in multiple places before using each struct or should I create the object once in the top class and give it as parameters to all 100 methods of perhaps 20 different classes that should have access to this struct?
Do I have to get the singleton object for different methods even though they are in the same class?
Can a singleton object get in one place in class and the whole class use it as a class member?
Use a member variable in your header file and initialize it in the constructor member initializer list:
Example Class2.h
#include "Class1.h"
class Class2 {
//...
private: // maybe public/protected to access from other classes
Class1& m_singleton_obj_cls1;
};
Example Class2.cpp
#include "Class2.h"
Class2::Class2()
: m_singleton_obj_cls1(Class1::getObject()) {
}
//...

Static member declaration c++11

I create a basic IBasic interface with a static field
class IBasic
{
public:
IBasic();
virtual ~IBasic();
static std::vector< std::vector<char> > Field;
};
from which the Inherit class is inherited:
class Inherit : public IBasic
{
public:
Inherit(int);
~Inherit();
void Foo();
};
The Inherit class makes some manipulations with Field static member in constructor/or member function.
In order to create an instance of the Inherit class, we need to explicitly declare a static field in the main.cpp before the main function:
#include "Basic.h"
#include "Inherit.h"
std::vector< std::vector<char> > IBasic::Field;
int main()
{
Inherit(10);
return 0;
}
The questions are:
In what namespace does the static method actually exists (global?)? Because I know that static field/function is not a class member in fact.
Is there another way to declare this static method, for example, in a
class file, inside a main function, or through creation unnamed namespace? Is it only one right variant?
How is right? What should be considered first of all?
A static member of a class is a member of its class (that's a tautology) and its class namespace (a class is a namespace). It is not a nember of any other namespace.
A non-const static data member of a class must be defined exactly once in a program, outside of any class, in the same namespace its class is defined in (a global namespace in your case). A header file is inappropriate place for such declaration. It is normally placed in an implementation .cpp file that goes together with the header file.
Having said that, an interface should not have any static data members, much less public ones. It is most likely a grave design error.
In what namespace does the static method actually exists (global?)? Because I know that static field/function is not a class member in fact.
It is declared in scope of the class. In fact the static variable is a class member, your assumption is wrong.
Is there another way to declare this static method, for example, in a class file, inside a main function, or through creation unnamed namespace? Is it only one right variant?
The usual way is to define it in the translation unit that contains the function definitions for the class.
How is right? What should be considered first of all?
There's no right or wrong way, but as mentioned definition in the same translation unit as the class function definitions is the usual way.
Here's an example usage of a static member without any inheritance.
SomeClass.h
#ifndef SOME_CLASS_H
#define SOME_CLASS_H
class SomeClass {
private:
int x;
public:
static SomeClass* const get(); // Needed For Using class to get this pointer
SomeClass();
int getX() const { return x; }
void setX( int val ) { x = val; }
};
#endif // SOME_CLASS_H
SomeClass.cpp
#include "SomeClass.h"
static SomeClass* s_pSomeClass = nullptr;
SomeClass::SomeClass() {
s_pSomeClass = this;
}
SomeClass* const SomeClass::get() {
if ( nullptr == s_pSomeClass ) {
// throw exception
}
return s_pSomeClass;
}
Another class using above class as a static member
OtherClass.h
#ifndef OTHER_CLASS_H
#define OTHER_CLASS_H
class SomeClass; // Forward Declaration
class OtherClass {
private:
static SomeClass* pSomeClass; // The Static Member to this class
int y;
public:
OtherClass();
int getY() const { return y; }
void setY( int val ) { y = val; }
void useSomeClassToSetY();
};
#endif // OTHER_CLASS_H
OtherClass.cpp
#include "OtherClass.h"
#include "SomeClass.h"
SomeClass* OtherClass::pSomeClass = nullptr;
OtherClass::OtherClass() {
if ( nullptr == pSomeClass ) {
pSomeClass = SomeClass::get();
}
}
void OtherClass::useSomeClassToSetY() {
// First Set X To Some Value:
pSomeClass->setX( 10 ); // Use of Static Member
y = pSomeClass->getX(); // Use of Static Member
}
Static members still belong to the class, but they have static storage.

using singleton class to be reached from all classes

I have a weird question. It is so weird it is probably quite easy to solve.
I created a software and I need to implement a class Sing with an sing objeect that must be reached from all classes from the software. Therefore I created it as singleton object in the main function.
My problem is, how can the object sing be reached from other classes (like ClassA) without creating pointers which are handovered by a pointer to every single class in the code.
All the class definition is located in the sing.h file. If I put the definition into the sing.cpp file the compiler will fail.
I managed to create this sing object, but it is not visible from ClassA. How can the object sing be seen without handing over pointers to the constructors of each class?
sing.h file:
#ifndef _SING_H_
#define _SING_H_
//declaration
class Singleton
{
public:
static Singleton* Instance();
static Singleton* InstanceSlave();
int a;
int setTest(int);
protected:
Singleton(){}
private:
static Singleton* _instance;
static Singleton* _instanceSlave;
};
//definitions (only work in header file, not in .cpp file
Singleton* Singleton::_instance =0;
Singleton* Singleton::Instance()
{
if (_instance == 0 )
{
_instance = new Singleton;
}
return _instance;
}
int Singleton::setTest(int b)
{
return 1;
}
#endif _CONF_H_
main.cpp file:
int main()
{
Singleton* sing = sing->Instance();
sing->setTest(2);
ClassA* classa = new ClassA();
}
main.h file:
#inlucde <iostream>
#include "sing.h"
#include "classA.h"
inside the ClassA I would like to have something like this:
classA.h
#inlude sing.h
class classA
{
public:
void doSomeThing(int);
}
classA.cpp:
#include ClassA.h
{
void ClassA::doSomeThing(int a)
{
sing.setTest(a);
}
}
My problem is, how can the object sing be reached from other classes (like ClassA) without creating pointers which are handovered by a pointer to every single class in the code.
The canonical way is to use Scott Meyer's Singleton and provide a static function like
static Singleton& Instance() {
static Singleton theInstance;
return theInstance;
}
Usage is
Singleton::Instance().setTest(2);
In general the Singleton Pattern isn't really considered a good technique, because the coupling with the rest of the code is too tight. It's better to use interfaces (abstract classes) and pass these around as necessary.
Just use
Singleton::Instance()->setTest(a);

C++ Singleton: `Undefined reference to` error

I am trying to implement a singleton design pattern without memory allocation. I tried searching for a solution but it seems like every solution was for a singleton defined with memory allocation.
I made the constructor private and the only code I added to the header file to make this a singleton design pattern was:
static ParametersServerPC& ParametersServerPC::GetInstance() {
static ParametersServerPC instance;
return instance;
}
This is a derived class from the base class ParametersServerABS which has an empty constructor definition. ParametersServerABS is an abstract class.
When I try to instantiate a ParametersServerPC class in a separate file:
ParametersServerPC& paramServer = ParametersServerPC::GetInstance();
I get this error:
undefined reference to `ParametersServerPC::GetInstance()'
Here are the .cpp and .hpp files:
parameters_server_abs.hpp:
#ifndef PARAMETERS_SERVER_ABS_HPP_
#define PARAMETERS_SERVER_ABS_HPP_
class ParametersServerABS {
public:
ParametersServerABS();
~ParametersServerABS();
virtual bool Load() = 0;
};
#endif
parameters_server_abs.cpp:
#include "mid_level/parameters_server_abs.hpp"
ParametersServerABS::ParametersServerABS() {}
ParametersServerABS::~ParametersServerABS() {}
parameters_server_pc.hpp:
#ifndef PARAMETERS_SERVER_PC_HPP_
#define PARAMETERS_SERVER_PC_HPP_
#include <string>
#include "mid_level/parameters_server_abs.hpp"
class ParametersServerPC: public ParametersServerABS {
public:
~ParametersServerPC();
static ParametersServerPC& GetInstance();
virtual bool Load();
private:
ParametersServerPC(std::string parameterFileName = "parameters.txt");
std::string _parameterFileName;
};
parameters_server_pc.cpp:
#include "mid_level/parameters_server_pc.hpp"
ParametersServerPC::ParametersServerPC(std::string parameterFileName = "parameters.txt") :
_parameterFileName(parameterFileName) {
}
ParametersServerPC::~ParametersServerPC() {
}
static ParametersServerPC& ParametersServerPC::GetInstance() {
static ParametersServerPC instance;
return instance;
}
virtual bool ParametersServerPC::Load() {
return true; // TODO
}
my_test_file.cpp
#include "mid_level/parameters_server_pc.hpp"
ParametersServerPC& paramServer = ParametersServerPC::GetInstance();
undefined reference to `ParametersServerPC::GetInstance()'
This seems to be a linker error. If you can post the output of the compilation console we might narrow this down further.
In the meantime you could check your build system and see if you omitted some source files from compilation.
On the singleton pattern there are already some good answers. More on the topic in a description of the pattern and in a general question about singletons.
It is an acceptable pattern. Here is a MVCE demonstrating the feasability :
#include <iostream>
#include <string>
using namespace std;
class A {
public:
int ival;
string strval;
static A& getInstance();
private:
A(int ival, string strval): ival(ival), strval(strval) {}
A(A& src): ival(src.ival), strval(src.strval) {}
~A() {};
};
A& A::getInstance() {
static A instance(1, "foo");
return instance;
}
int main() {
A& a = A::getInstance();
cout << a.ival << endl;
// A a1 = A::getInstance(); error
// A a2 = a; error
// A a3(2, "bar"); error
return 0;
}
First, mark your ~ParametersServerABS(); destructor virtual to be able to delete objects properly. Second, you need to remove virtual and static keywords from parameters_server_pc.cpp file: they are only for definitions (for your header file).
Next, do it right:
class ParametersServerPC {
// your code
private:
ParametersServerPC(std::string parameterFileName = "parameters.txt");
ParametersServerPC(ParametersServerPC const&) = delete;
void operator=(ParametersServerPC const&) = delete;
};
Singleton means that you can't get copies of an object: you need to forbid using of copy constructor and copy assignment operator.
And anyway I think your problem is in static in your parameters_server_pc.cpp file. Remove it from implementation part (cpp file) in order to fix the problem but LEAVE it in the definition part (header file).

Force Templated Constructor to Run?

I know there is a initailzer trick to forcing a global object to be constructed regardless of where it is used. This is used for std::cout i believe.
#ifndef GUARD_H
#define GUARD_H
class Magical
{
// default constructor and such...
};
class Init
{
public:
Init();
};
extern Magical& magic;
namespace
{
Init __magical_initializer; // works as this object is constructed in every source file it is included in
}
#endif
src:
#include "magical.h"
#include <new>
static int count; // believe there is a spec somewhere which states global integers are initialized with zero
static alignas(Magical) char buffer[sizeof(Magical)];
Magical& magic = *reinterpret_cast<Magical*>(buffer);
Init::Init()
{
if(!count++)
{
new(buffer) Magical;
}
}
I was wondering if there was a template equivalent to this, as such my code would look something like this:
template<typename T>
class Base
{
static Magical<T> __private; // need this constructor to be called.
};
// usage:
class SomeClass : public Base<SomeClass>
{
};
No way to solve this problem as templates can't exist in source files.