[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Static member functions in template classes and inlining
From: |
tchernobog |
Subject: |
Static member functions in template classes and inlining |
Date: |
22 Jun 2006 08:41:45 -0700 |
User-agent: |
G2/0.2 |
First of all, hi to everybody! This is my first post here.
I'm encountering a nasty problem in developing an application of mine.
I've got a main executable and some dynamic modules that can be loaded
by it. Both the executable and modules do link to a shared library
called "libbackend.so".
Into libbackend.so, I've put some objects that follow the Singleton
pattern. So I've created a template like this (it uses a Glib::Mutex
object you can easily ignore for thread-safeness):
-------- # code -------
template<typename Instantiated_class>
class Singleton
{
public:
static Instantiated_class& get_instance();
private:
static Instantiated_class* _instance;
static Glib::StaticMutex _mutex;
}; //~ class Singleton
template<typename Instantiated_class>
Instantiated_class*
sgpem::Singleton<Instantiated_class>::_instance = NULL;
template<typename Instantiated_class>
Glib::StaticMutex
sgpem::Singleton<Instantiated_class>::_mutex =
GLIBMM_STATIC_MUTEX_INIT;
template<typename Instantiated_class>
Instantiated_class&
sgpem::Singleton<Instantiated_class>::get_instance()
{
Glib::Mutex::Lock lock(_mutex);
if(_instance == NULL)
_instance = new Instantiated_class();
return *_instance;
}
---- # end code ----
This means that each Singleton I want to have into libbackend.so has
just to do:
-------- # code -------
class SomeClass : public Singleton<SomeClass>
{
friend class Singleton<SomeClass>;
public:
// ...
private:
SomeClass();
SomeClass(const SomeClass&);
}; //~ SomeClass
---- # end code ----
Now, the problem I noticed is that what should be a unique instance of
SomeClass (the one that dwells into libbackend.so) is instantiated
multiple times when the program begins, instead of really the first
time that SomeClass::get_instance() is called.
After investigating this for a little, I discovered that:
$ nm -C .libs/libbackend.so | grep get_instance
0000cd90 W sgpem::Singleton<sgpem::SomeClass>::get_instance()
00010b00 W sgpem::Singleton<sgpem::SomeOtherClass>::get_instance()
$ nm -C .libs/mainexecutable | grep get_instance
08051460 W sgpem::Singleton<sgpem::SomeClass>::get_instance()
08056e70 W sgpem::Singleton<sgpem::SomeOtherClass>::get_instance()
$ nm -C .libs/loadablemodule | grep get_instance
00004cd0 W sgpem::Singleton<sgpem::SomeClass>::get_instance()
00005010 W sgpem::Singleton<sgpem::SomeOtherClass>::get_instance()
So, my guess is that get_instance() of the Singleton template is
inlined and included into both the main executable and each module.
This is why calling SomeClass::get_instance() from one place returns a
SomeClass object, from another place it returns another unrelated
SomeClass object.
I'm not sure how to solve this. Of course, I can drop the template
completely and use the "standard way" to make every class I need a
Singleton, but I rather liked the idea of this approach. :-)
Maybe there's a GCC attribute to prevent inlining for a function,
although I'd prefer to not to use compiler-dependent flags for this.
So, how can i get the symbols for Singleton<SomeClass> to be marked "T"
(global exported symbols into the text section) in libbackend.so and
"U" (undefined) in the main executable and modules?
Thanks for any answer,
Matteo
PS: if I got it wrong, apologies in advance. I'm a student after all,
of course I behave stupidly! :-)
- Static member functions in template classes and inlining,
tchernobog <=