By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,691 Members | 1,123 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,691 IT Pros & Developers. It's quick & easy.

Instansing singleton right in the header file

P: n/a
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();
}

Mar 17 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Raider wrote:
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
--
Please remove capital As from my address when replying by mail
Mar 17 '06 #2

P: n/a
Raider wrote:
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
----------------------
#pragma once
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
----------------------
#include <iostream>
Unnecessary here.
#include "Singleton.h"

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


Cheers! --M

Mar 17 '06 #3

P: n/a
Raider wrote:
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.

Mar 17 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.