help-gplusplus
[Top][All Lists]
Advanced

[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! :-)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]