0

I am trying to implement a Singleton class in C++ and getting a bit confused. Ok, let's say I have the following 2 classes:

class Animal { public: virtual int age() = 0; virtual void breed() = 0; }; class Cat : public Animal { public: Cat(); int age(); void breed(); }; 

more classes involved in this system .... (dog, fish etc)

Now I have a singleton class which I can just use 1 object:

class Singleton { public: Animal *newAnimal(string theTypeOfAnimal); private: static Animal* pinstance; }; Animal *Singleton::newAnimal(string theTypeOfAnimal) { pinstance = new Cat; } int main() { Singleton *s; return 0; } 

UPDATE:

New code:

#include <iostream> using namespace std; class Animal { public: virtual int age() = 0; virtual void breed() = 0; }; class Cat : public Animal { public: virtual int age() { return 9; } virtual void breed() { } }; class Singleton { public: Animal *newAnimal(string theTypeOfAnimal); private: static Animal* pinstance; }; Animal* Singleton::pinstance = 0; Animal *Singleton::newAnimal(string theTypeOfAnimal) { this->pinstance = new Cat; return pinstance; } int main(int argc, char *argv[]) { Singleton s; Animal *myAnimal = NULL; Animal *myAnimal = s->newAnimal("cat"); 

}

2
  • 4
    Stay away from Singleton antipattern if possible. If you need common state use stateless classes that enwrap access to that common state. Sooner or later that common state wants to split. Commented Oct 27, 2012 at 22:54
  • @WaleedKhan I have updated the code and included the error message! Commented Oct 27, 2012 at 23:21

3 Answers 3

1

You must define static class object outside of it:

Animal* Singleton::pinstance = 0; 

You must define functions in Cat class:

class Cat : public Animal { public: Cat() {} int age() { return 7; } void breed() {} }; 
Sign up to request clarification or add additional context in comments.

2 Comments

Updated the code. Got a new error: "member reference type 'Singleton' is not a pointer Animal *myAnimal = s->newAnimal("cat");"
@Phorce myAnimal = s.newAnimal("cat"); 1) You has redefined myAnimal second time; 2) You used -> on a local object insteda of .;
1

You need to explicitly define your static member: Animal *Singleton::pinstance = nullptr;

static Animal* pinstance inside the class is just a declaration, i.e. no real space is allocated for the variable. The reason for that is that static members do not belong to a specific object and aren't allocated with instance of the hosting class. Static members are shared along all the class instances and must be allocated explicitly.

2 Comments

thank you for your input BUT I kinda get it, but, then I don't.. I've tried putting the Animal *Singleton::pinstance = null; but doesn't work!
there is no null, there is nullptr and you must define it outside the class, at global scope.
0

You must derive from singleton, not from target calss. Singleton is a pattern. You can implement it as a template class (usually) or base class to derive from (rare). Classic singleton has:

  • private constructor
  • privace copy-constructor
  • private non-virtual destructor
  • private operator=
  • holds pointer to self object
  • has external friend function to obtain object

It can:

  • have no implementation for ctor, cctor, dtor and oper=, so trying to call it from derived class will lead to linkage error
  • derive children privately
  • lazy object initialization
  • ... anything more

There is no consensus on which implementation is better and is Singleton good or bad. In my opinion singleton is more harmful than useful for beginners. Don't use it until you sure it need it in particular place.

As a desert a bad Singleton template with smart pointers (find horror errors!):

#include <memory> #include <boost/noncopyable.hpp> template <class T> class Singleton : public boost::noncopyable { public: static std::shared_ptr<T> Get() { if( m_pSelf.get() == 0 ) return m_pSelf = std::shared_ptr<T>(new T()); else return m_pSelf; } protected: Singleton(){} ~Singleton() {} private: static std::shared_ptr<T> m_pSelf; }; template <class T> std::shared_ptr<T> Singleton<T>::m_pSelf; 

2 Comments

Thank you. And for the code, although, I do not understand it that well.. Could you please look at my edited above code and tell me why I am getting the error posted, and, how I would fix it? Thank you :)!
-1 For the implementation. Returning a pointer to T makes the whole Singleton class pointless since there's nothing stopping me from copying T. In fact, having a singleton template is fairly pointless, might as well just make the original class a singleton.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.