How to share global object in other modules?

Pages: 123
I want to pass this pointer referencing to instance of MyGlobalClass because I need to access members of the object from within other modules.

Originally I tried this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MyGlobalClass{
public:
MyGlobalClass * pGlobInst = this;
std::vector<SRC> sources(1, pGlobInst);
std::vector<TARGET> destination(1, pGlobInst);

CLParser CLPars;
FILE_ File;

static int IsDirectory(std::string path);
MyGlobalClass(int argc, char* argv[]): 
CLPars(this), File(this) {
CLPars.ParseArgs(argc, argv);
};
};


But this brings error error C2355: 'this' : can only be referenced inside non-static member functions

Then I tried to make it static variable:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class MyGlobalClass;
class Shared { public: static const MyGlobalClass * globInst; };
class SRC : private Shared  {};
SRC::SRC(){PGlobalInstance:Shared::globInst;}
class TARGET : private Shared  {}
TARGET::TARGET(){
	PGlobalInstance:Shared::globInst;
};

class MyGlobalClass : private Shared {
private:
	void Initiate();
public:
	std::vector<SRC> sources;
	std::vector<TARGET> destination;
	CLParser CLPars;
	FILE_ File;
	MyGlobalClass(int argc, char* argv[]): 
		CLPars(this), File(this) {
		Initiate();
	}
};


But this also produces error when I want to change the parent object member from within the modules. Getting errors membername cannot be modified because it is being accessed through a const object . If I would remove the const so I will get error C2355 , the same as in the begin.

So how to solve this?
Last edited on
I think I have found the problem reading this tutorial:
http://www.yolinux.com/TUTORIALS/C++Singleton.html

I need to call static function to create new instance of type MyGlobalClass main object and return static pointer which will be shared across all modules.

The biggest mistake was the try to assign pointer to static object this, because static functions cannot access this pointer to object/instance.

Hence this was wrong
1
2
3
4
void MyGlobalClass::Initiate() {
	MyGlobalClass *pGlobInst = this;
    Shared::globInst = pGlobInst;
}

and should be
1
2
3
4
MyGlobalClass* MyGlobalClass::Initiate() {
    pGlobalInstance new MyGlobalClass;
    return pGlobalInstance;
}


Should I also create destructor for pGlobalInstance?
Gang of Four singleton design does not have destructor, relying on automatic memory freeing after program termination. (you can use atexit() handler to delete it properly)

In C++11 it is better to use Meyers implementation of Singleton (thread safe, returns reference instead of pointer)
http://stackoverflow.com/questions/17712001/how-is-meyers-implementation-of-a-singleton-actually-a-singleton
http://www.codeproject.com/Articles/4750/Singleton-Pattern-A-review-and-analysis-of-existin
Ok, so I find Meyers Singleton:

http://www.viewdocsonline.com/document/5z8fni

(source: C++ In Theory: The Singleton Pattern, Part I
- http://www.devarticles.com/c/a/Cplusplus/C-plus-plus-In-Theory-The-Singleton-Pattern-Part-I/4/)

however it is not quite clear why he does not use new to create new instance...

Log &myLog = Log::Instance(); should return reference to instance but I don't see creation of the object... It looks like the article should continue, but it doesn't. Pitty. I am quite interested about it. I think there must be some function to create new instance.
Meyers singleton is simple:
1
2
3
4
5
bar& foo()
{
    static bar baz; //Here is the object which will be returned
    return baz;
}
As static objects created when first referenced and is not recreated after, instead sharing that instance between all function calls, it is guaranteed to return reference to the same object for all function calls. Also it is inherently thread safe (by standard) and destructor will be called during correct program termination. So you do not have to think wh is responsible for destroying it, making RAII singletones safer.

That singleton shares GoF singleton pros (like single instance, global access, late initialization) and lack cons (thread safety, manual destruction)
Last edited on
When I try the Gang of Four singleton I still get error C2512: 'MyGlobalClass' : no appropriate default constructor available.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class MyGlobalClass : private Shared {
private:
	MyGlobalClass * PGlobalInstance;
	static void Initiate();
public:
	std::vector<SRC> sources;
	std::vector<TARGET> destination;

	CLParser CLPars;
	FILE_ File;
		
	MyGlobalClass(int argc, char* argv[]);
};

MyGlobalClass::MyGlobalClass(int argc, char* argv[]) : Shared()
	{	
	Initiate();
// CLParser * CLPars( this );
// FILE_ * File( this );
// CLPars.ParseArgs(argc, argv);
};

void MyGlobalClass::Initiate() {
	MyGlobalClass *pGlobInst = new MyGlobalClass();
    Shared::globInst = pGlobInst;
}

I still cannot find out how to solve it. I tried initialization list with no success.

The error is to this line:
MyGlobalClass *pGlobInst = new MyGlobalClass();
Last edited on
new MyGlobalClass(); You are trying to call default constructor which your class lack. Either provide it or call another constructor.
Is it possible to initiate non static data member (pointer) to static class data member?

file.h
1
2
3
4
class FILE_ : private Shared {
private:
	MyGlobalClass * PGlobalInstance;
};


file.cpp:
1
2
3
4
5
#include "stdafx.h"

FILE_::FILE_(){
}
FILE_::PGlobalInstance = Shared::globInst;


This produces error and it's not clear to me how can I set the non static member - pointer FILE_::PGlobalInstance to the pointer to the singleton.
OOps I missed mistake in implementation of singletone in your class:

PGlobalInstance should be static
And taht is the line which hides that error: MyGlobalClass *pGlobInst = new MyGlobalClass();
It should be pGlobInst = new MyGlobalClass();
If you refer to class itself (throught class name) instead of instance, you can access only static members.
According the tutorial http://www.yolinux.com/TUTORIALS/C++Singleton.html
Logger::Instance()->openLogFile("logFile.txt");

1
2
3
4
5
6
class Logger{
public:
   static Logger* Instance();
   bool openLogFile(std::string logFile);
   void writeToLogFile();
   bool closeLogFile();


So Instance() is static function and returns static result, however this way thay can access openLogFile() which is not static and so can access non static members. Right?

I was just thinking if I have saved the pointer as static member, how then I can access the pointer by non-static functions or make non-static calls. So every time I want to call some non-static function I must to call MyGlobalClass->instance()->someNonStaticFunction() otherwise it is not possible to access the globalInstance of the class which contains non static members...

But it's still not clear to me. Should I create the
pGlobInst = new MyGlobalClass();
to every module or just to instance()?
Because there is no MyGlobalClass().

The initiate() does something different:

1
2
3
4
void MyGlobalClass::Initiate(int argc, char* argv[]) {
	MyGlobalClass *pGlobInst = new MyGlobalClass(argc, argv);
    Shared::globInst = pGlobInst;
}


Initiate should be run only once because it parses arguments from command line and prepares program to start.

So again:
I am starting to create base class first:

1
2
3
class Shared { public: static Glob * globInst;
static Shared* instance();
};

and define the
1
2
3
4
5
Shared* Shared::globInst = 0;  // Global 
Shared* Shared::instance()
{   
	return globInst; 
}
Last edited on
continue of the last post:

bitmap.h(3): error C2143: syntax error : missing ';' before '*'
bitmap.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
bitmap.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
bitmap.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(16): error C2143: syntax error : missing ';' before '*'
main.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(47): error C2143: syntax error : missing ';' before '*'
main.h(47): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(47): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
file.h(3): error C2143: syntax error : missing ';' before '*'
file.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
file.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
file.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
clparser.h(3): error C2143: syntax error : missing ';' before '*'
clparser.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
clparser.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
clparser.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.cpp(4): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.cpp(4): error C2440: 'initializing' : cannot convert from 'Glob *' to 'int'
There is no context in which this conversion is possible
main.cpp(8): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.cpp(8): error C2374: 'PGlobalInstance' : redefinition; multiple initialization
main.cpp(4) : see declaration of 'PGlobalInstance'
main.cpp(8): error C2440: 'initializing' : cannot convert from 'Glob *' to 'int'
There is no context in which this conversion is possible
global.cpp
bitmap.h(3): error C2143: syntax error : missing ';' before '*'
bitmap.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
bitmap.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
bitmap.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(16): error C2143: syntax error : missing ';' before '*'
main.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(47): error C2143: syntax error : missing ';' before '*'
main.h(47): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(47): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
file.h(3): error C2143: syntax error : missing ';' before '*'
file.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
file.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
file.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
clparser.h(3): error C2143: syntax error : missing ';' before '*'
clparser.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
clparser.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
clparser.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
global.cpp(3): error C2653: 'MyGlobalClass' : is not a class or namespace name
global.cpp(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
global.cpp(4): error C2550: 'MyGlobalClass' : constructor initializer lists are only allowed on constructor definitions
global.cpp(8): warning C4508: 'MyGlobalClass' : function should return a value; 'void' return type assumed
global.cpp(10): error C2653: 'MyGlobalClass' : is not a class or namespace name
global.cpp(11): error C2065: 'pGlobInst' : undeclared identifier
global.cpp(11): error C2061: syntax error : identifier 'MyGlobalClass'
file.cpp
bitmap.h(3): error C2143: syntax error : missing ';' before '*'
bitmap.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
bitmap.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
bitmap.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(16): error C2143: syntax error : missing ';' before '*'
main.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(47): error C2143: syntax error : missing ';' before '*'
main.h(47): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.h(47): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
file.h(3): error C2143: syntax error : missing ';' before '*'
file.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
file.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
file.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
clparser.h(3): error C2143: syntax error : missing ';' before '*'
clparser.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
clparser.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
clparser.h(3): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
file.cpp(5): error C2039: 'PGlobalInstance' : is not a member of 'FILE_'
file.h(1) : see declaration of 'FILE_'
file.cpp(5): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
file.cpp(5): error C2440: 'initializing' : cannot convert from 'Glob *' to 'int'
There is no context in which this conversion is possible
file.cpp(115): error C2227: left of '->readDirectoryFiles' must point to class/struct/union/generic type
type is 'int'
file.cpp(121): error C2227: left of '->readDirectoryFiles' must point to class/struct/union/generic type
type is 'int'
definitions.cpp

is all after I added static to declaration of the instance pointer:
static MyGlobalClass * PGlobalInstance;
the error is to the previous line.

But this one is defined:
__BITMAP::PGlobalInstance = Shared::instance();
Last edited on
The point of singletone is that whoever calls it first is responsible for it creation. Function which returns instance should handle creation if instance does not exist. It should handle loading needed parameters somehow.

Creating new instance in every module is counter-productive and defeats meaning of singleton and global access point.

You can have init function, but first loook at what you have:
local variable pGlobInst
static variable PGlobalInstance
static variable globInst

Looks like you lost in your own code, abused inheritance too much and your architecture smells fishy.
I did not say I want create new instance in every module! I said is the function instance should be created for every module. But it is clear now to me that it should stay in the base class.

I need to remember that

1) singleton instance() is placed in the base class whereas create() or initiate() function to create instance is in the derived class (MyGlobalClass).

2) The pointer which will store the result of the new MyGlobalClass() is the static member from the base class.

3) there is no need to create static member (pointer to instance) to keep the reference. The derived classes have the access to static method instance() which is called to gain access to instance of MyGlobalClass.
Last edited on
I renamed class MyGlobalClass to class G. Also I moved the singleton class to separate file.

Now getting new error:

1
2
3
4
Shared* Shared::instance()
{   
	return globInst; 
}


singleton.cpp(7): error C2243: 'type cast' : conversion from 'G *' to 'Shared *' exists, but is inaccessible

Maybe last error.
Last edited on
YOur singleton class and class returning instance are different classes?
Generally you should return instance from same class as instance type.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/** Global Class  - singleton.h**/
class G;	      // "global" class - Forward declaration
class Shared { // class to be derived by other modules
	public: static G * globInst; // is to be set obly once in main class G
	static Shared* instance(); // will return instance of "global" class (the main class G)
};

/** Global Class  - global.cpp**/
#include "stdafx.h"
G::G(int argc, char* argv[]) : Shared()
	{	
};

void G::Initiate(int argc, char* argv[]) {
	globInst = new G(argc, argv); // save the pointer to Shared::globInst
}


G is derived from the Shared (singleton class)
Last edited on
Why inheritance? Why not move all it in a single class?

Inheritance should be used only when it is needed.
Storing pointers to a child class is generally sign of bad design.

Singletons are usually should be a final class (unless it is abstract interface or template for easy creation of concrete singletones)
Last edited on
It was in the turotiral, they showed example of "C++ Singleton class using" inheritance.

How would the other classes have access to instance()? I would need to make it global static function. Is that your idea?
I would need to make it global static function.

No.

Answer this: Who can call a static member function of a class?
Pages: 123