Instansing singleton right in the header file

R

Raider

I need to have one object for each template argument(s) used. For
example, I need to have one object of int. I tried the following code
and it gives me all I want with Visual C++ 7.1. But is it portable???
Will all compilers produce code that prints "single"?

Instancing of object right in header file (that can be include multiple
times - i.e. in multiple cpp files) give rise to my doubts...


Singleton.cpp
----------------------
#pragma once
template <typename T>
class Singleton
{
public:
static T * GetInstance()
{
static T Instance;
return &Instance;
}
};


First.cpp
----------------------
#include <iostream>
#include "Singleton.h"

void * First()
{
return Singleton<int>::GetInstance();
}

void * Second();

int main()
{
std::cout << (First() == Second() ? "single" : "multiple" );
std::cout << std::endl;
return 0;
}


Second.cpp
----------------------
#include <iostream>
#include "Singleton.h"

void * Second()
{
return Singleton<int>::GetInstance();
}
 
V

Victor Bazarov

Raider said:
I need to have one object for each template argument(s) used. For
example, I need to have one object of int. I tried the following code
and it gives me all I want with Visual C++ 7.1. But is it portable???

Of course.
Will all compilers produce code that prints "single"?

All compliant ones will.
Instancing of object right in header file (that can be include multiple
times - i.e. in multiple cpp files) give rise to my doubts...

You're not instantiating it "in header file". You're instantiating it
in a function. By the time the function is generated, compiled, and
then executed, there are no header files (reminds me of "there is no
spoon" from the Matrix movie).
Singleton.cpp
----------------------
#pragma once
template <typename T>
class Singleton
{
public:
static T * GetInstance()
{
static T Instance;
return &Instance;
}
};


First.cpp
----------------------
#include <iostream>
#include "Singleton.h"

void * First()
{
return Singleton<int>::GetInstance();
}

void * Second();

int main()
{
std::cout << (First() == Second() ? "single" : "multiple" );
std::cout << std::endl;
return 0;
}


Second.cpp
----------------------
#include <iostream>
#include "Singleton.h"

void * Second()
{
return Singleton<int>::GetInstance();
}

V
 
M

mlimber

Raider said:
I need to have one object for each template argument(s) used. For
example, I need to have one object of int. I tried the following code
and it gives me all I want with Visual C++ 7.1. But is it portable???
Will all compilers produce code that prints "single"?

Instancing of object right in header file (that can be include multiple
times - i.e. in multiple cpp files) give rise to my doubts...

Absent the export keyword (which itself is not very portable at the
moment), templates *must* be defined in the header file. The
compiler/linker will make sure there is actually only one instance in
the the final product.
Singleton.cpp

Non-standard. Prefer #ifndef include guards.
template <typename T>
class Singleton
{
public:
static T * GetInstance()
{
static T Instance;
return &Instance;
}
};

You might consider returning a reference and disabling some other
functions just for safety:

private:
Singleton();
Singleton( const Singleton& );
Singleton& operator=( const Singleton& );
Singleton* operator&();
~Singleton();
First.cpp
----------------------
#include <iostream>
#include "Singleton.h"

void * First()
{
return Singleton<int>::GetInstance();
}

void * Second();

int main()
{
std::cout << (First() == Second() ? "single" : "multiple" );
std::cout << std::endl;
return 0;
}


Second.cpp

Unnecessary here.
#include "Singleton.h"

void * Second()
{
return Singleton<int>::GetInstance();
}

Cheers! --M
 
A

Axter

Raider said:
I need to have one object for each template argument(s) used. For
example, I need to have one object of int. I tried the following code
and it gives me all I want with Visual C++ 7.1. But is it portable???
Will all compilers produce code that prints "single"?

Instancing of object right in header file (that can be include multiple
times - i.e. in multiple cpp files) give rise to my doubts...


Singleton.cpp
----------------------
#pragma once
template <typename T>
class Singleton
{
public:
static T * GetInstance()
{
static T Instance;
return &Instance;
}
};


First.cpp
----------------------
#include <iostream>
#include "Singleton.h"

void * First()
{
return Singleton<int>::GetInstance();
}

void * Second();

int main()
{
std::cout << (First() == Second() ? "single" : "multiple" );
std::cout << std::endl;
return 0;
}


Second.cpp
----------------------
#include <iostream>
#include "Singleton.h"

void * Second()
{
return Singleton<int>::GetInstance();
}

The code is not portable because it's using #pragma once instead of
standard header guards.
I'm guessing that Singleton.cpp is a typo, since it should be
Singleton.h

If you have a limitted set of types you want to use with your Singleton
template class, there is a way to put the implementation inside a *.cpp
file (even if you don't have export keyword support).
You can do template forward declaration.
Example:
//Your Singleton.cpp
template Singleton<int>;
template Singleton<std::string>;
#include "foofoo.h"
template Singleton<foofoo>;
//Your Singleton implementation here


If you have the above code in the Singleton.cpp file, than you can
create an instance of your Singleton template of type int, std::string,
or foofoo.
If you used a different type, than you would get a linker error.
This method is only usefull if you're only going to support limitted
types for your Singleton template.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top