#include <iostream>
using namespace std;
class singleton
{
protected:
singleton() { };
singleton(const singleton &) { };
singleton & operator= (const singleton &) { return *this; };
};
class foo
{
public:
//foo() { }; // The program runs if this line is not commented out.
singleton a, b, c;
};
int main(void)
{
foo bar;
cout << "Foobar!" << endl;
return 0;
}
For brevity''s sake, the "singleton" here has no ability to maintain the single instance. But that''s not relevant, the weird thing here is that, if the foo class is declared with a constructor, the program will compile without error (under MetroWerks Codewarrior) despite the fact that it should not be possible to instantiate a class that contains singleton members. If the constructor in foo is commented out, the program does not compile, and generates an error for invalid use of a protected/private member.
I''m hoping that someone more familiar with this sort of thing can explain what''s wrong here, and how to implement a proper singleton.
Problem enforcing a singleton - Part Deux
I want to make a Singleton class that has the singleton pattern enforced. I want to make it so that it is not possible to create multiple instances of the singleton. I''m using C++. The following code behaves strangely, and I would appreciate it if someone could explain why:
quote:If the constructor in foo is commented out, the program does not compile, and generates an error for invalid use of a protected/private member.
That is standard behavior. I do not understand why the foo constructor would make it compile, though. foo::foo () should be invoking singleton::singleton () implicitly for foo::a, foo::b, and foo::c. Sounds like a compiler bug to me.
quote:I''m hoping that someone more familiar with this sort of thing can explain what''s wrong here, and how to implement a proper singleton.
That depends on what kind of singleton you need.
Maybe it could be a bug with the compiler. It could be optimizing out the singleton members since they are never used, before trying to construct them. The effect of having the default constructor could be having some weird interaction with this sort of thing.
The problem is that the class singleton has no relationship whatsoever to class foo. That means, from class foo''s viewpoint, singleton cannot created, because the default ctor, copy ctor, and assignment operator are all protected, and not public.
It''s no compiler bug, just the semantics of the C++ language at work.
This is how I implement 90% of my singletons:
It''s no compiler bug, just the semantics of the C++ language at work.
This is how I implement 90% of my singletons:
#include <cassert>template<typename TypeT>class Singleton{public: Singleton() { assert(sInstance == 0); sInstance = static_cast<TypeT*>(this); } ~Singleton() { assert(sInstance != 0); sInstance = 0; } static TypeT& GetInstance() { assert(sInstance != 0); return *sInstance; }protected: static TypeT* sInstance;};template<typename TypeT>TypeT* Singleton<TypeT>::sInstance = 0;
Try this....
This guarantees that you only access the singleton instance from the static public method instance.
So wherever you need an instance, just do this:
Singleton* mySingleton = Singleton::Instance();
Hope this helps
class Singleton {public: static Singleton* Instance();protected: Singleton();private: static Singleton* _instance;};Singleton* Singleton::_instance = 0;Singleton* Singleton::Instance() { if(_instance == 0) _instance = new Singleton(); return _instance;}
This guarantees that you only access the singleton instance from the static public method instance.
So wherever you need an instance, just do this:
Singleton* mySingleton = Singleton::Instance();
Hope this helps
OP, its a compiler bug.
gcc 2.95 gives errors both ways, which is how it should be expected.
Just add an assert(m_instance==NULL) equivalent in the constructor just to be sure that you don''t accidentally create more than one while using the broken compiler.
gcc 2.95 gives errors both ways, which is how it should be expected.
Just add an assert(m_instance==NULL) equivalent in the constructor just to be sure that you don''t accidentally create more than one while using the broken compiler.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement