CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Dec 2006
    Posts
    154

    template classes & static members

    Hey,

    Here is my problem :

    i am building an exectutable which relies on two Dlls, one is the "core" and the other is "engine"

    in Core, i define a Singleton class :

    Code:
    template< class T >
    class Singleton
    {
       static T* instance;
    public:
       Singleton() : instance(reinterpret_cast<T*)(this)) {}
       static T* getInstance() { assert(instance); return instance; }
    };
    in Engine, i use this Singleton :
    Code:
    class Toto : public Singleton<Toto>
    {
    };
    
    void register_toto(); //this function creates the singleton from within the engine, just calling new(Toto)
    at last, in the exe, i use the instance :
    Code:
    Toto::getInstance();
    which raises...or not the assert. Under Visual Studio it seems to work OK, but under mingw the singleton is a static member initialized in engine, and since it's in a header file, the exe also got its own copy of the static member, and thinks it's not initialized. So i have an initialized singleton in Engine and an empty one in the program.

    what can I do to have only one static member both for the Dll and the exe?

  2. #2
    Join Date
    Dec 2006
    Posts
    154

    Re: template classes & static members

    i've changed my mind, it doesn't work either in Visual Studio

    so now how do i make this work? ^_^

    here is the code in three different files :
    Code:
    //singleton.h
    #include <cassert>
    
    template< class T >
    class Singleton
    {
       static T* instance;
    public:
        Singleton() { instance=reinterpret_cast<T*>(this);}
       static T* getInstance() { assert(instance); return instance; }
    };
    
    template<class T>
    T* Singleton<T>::instance = 0;
    
    class Toto : public Singleton<Toto>
    {
    };
    
    #ifdef _USRDLL
    __declspec(dllexport)
    #else
    __declspec(dllimport)
    #endif
    void register_toto(); //this function creates the singleton from within the engine, just calling new(Toto)
    Code:
    //dll.cpp
    #include "singleton.h"
    
    void register_toto()
    {
        new Toto;
    }
    Code:
    //main.cpp
    #include "singleton.h"
    
    int main(void)
    {
        register_toto();
        Toto::getInstance();
    }

  3. #3
    Join Date
    Nov 2002
    Location
    Sofia, Bulgaria
    Posts
    661

    Re: template classes & static members

    Or you can make code which does not need to call an explicit initializing function.

    Like that:
    Code:
    template <class T>
    class Singleton
    {
    public:
        static T& getInstance();
        ~Singleton() {}
    protected:
        Singleton() {}
    };
    
    ...
    
    template <class T>
    T& Singleton<T>::getInstance()
    {
       static T t;
       return t;
    }
    and then inherit the desired classes in the manner described by you above.
    It's only when you look at an ant through a magnifying glass on a sunny day that you realise how often they burst into flames

  4. #4
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582

    Re: template classes & static members

    And if you're not using vc++ 6.0 (which has a bug), you can also make the destructor private.

    Jeff

  5. #5
    Join Date
    Dec 2006
    Posts
    154

    Re: template classes & static members

    this doesn't work, the static data in the functions get duplicated to if the code gets duplicated

  6. #6
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582

    Re: template classes & static members

    This works for me:

    Code:
    #include <iostream>
    
    using namespace std;
    
    template <class T>
    class Singleton
    {
    public:
    	static Singleton<T>& getInstance();
    
    	void set(T t) { m_t = t; }
    	T get() { return m_t; }
    
    private:
    	~Singleton() {}
    	Singleton() : m_t() {}
    
    	T m_t;
    };
    
    template <class T>
    Singleton<T>& Singleton<T>::getInstance()
    {
    	static Singleton<T> t;
    	return t;
    }
    
    int main()
    {
    	// first instances
    	{
    		Singleton<int>& is = Singleton<int>::getInstance();
    		is.set(42);
    		Singleton<double>& ds = Singleton<double>::getInstance();
    		ds.set(3.14);
    	}
    
    	// new instances
    	{
    		Singleton<int>& is = Singleton<int>::getInstance();
    		cout << is.get() << endl;
    		Singleton<double>& ds = Singleton<double>::getInstance();
    		cout << ds.get() << endl;
    	}
    }
    Jeff

  7. #7
    Join Date
    Dec 2006
    Posts
    154

    Re: template classes & static members

    this works in a single file, eventually in a single dll/exe thanks to vague linkage, but won't work through a Dll.

  8. #8
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582

    Re: template classes & static members

    Quote Originally Posted by screetch
    this works in a single file, eventually in a single dll/exe thanks to vague linkage, but won't work through a Dll.
    I missed the dll requirement. This will only work as statically linked.

    One option, if you know all the types that will be used, is to move the getInstace to an implementation file and instantiate each instance in the same file. I believe this will solve the dll problem.

    If you both an unbounded set of Singletons as well as a dll, I don't know how to solve this problem.

    Jeff

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured