2012-10-27 3 views
0

J'essaie d'implémenter une classe Singleton en C++ et je suis un peu confus. Ok, disons que j'ai les 2 classes suivantes:Singleton class - Vraiment confus

class Animal { 

public: 
    virtual int age() = 0; 
    virtual void breed() = 0; 
}; 


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

plus classes impliquées dans ce système .... (chien, etc poissons)

Maintenant, j'ai une classe singleton que je peux utiliser 1 objet:

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; 
}  

MISE À JOUR:

Nouveau 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"); 

}

+0

Quelle erreur obtenez-vous? –

+4

Restez à l'écart de Singleton antipattern si possible. Si vous avez besoin d'un état commun, utilisez des classes sans état qui permettent d'accéder à cet état commun. Tôt ou tard, cet état commun veut se séparer. –

+0

@WaleedKhan J'ai mis à jour le code et inclus le message d'erreur! – Phorce

Répondre

1

Vous devez définir l'objet de classe statique en dehors de celui-ci:

Animal* Singleton::pinstance = 0; 

Vous devez définir des fonctions dans Cat classe:

class Cat : public Animal 
{ 
public: 
    Cat() {} 
    int age() { return 7; } 
    void breed() {} 
}; 
+0

Mise à jour du code. Vous avez une nouvelle erreur: "le type de référence membre 'Singleton' n'est pas un pointeur Animal * myAnimal = s-> newAnimal (" cat ");" – Phorce

+0

@Phorce 'myAnimal = s.newAnimal (" cat ");' 1) Vous avez redéfini 'myAnimal' deuxième fois; 2) Vous avez utilisé '->' sur un objet local insteda de '.'; – Drop

+0

Résolu! Je pense, j'espère !! :RÉ! Merci quand même – Phorce

0

Vous devez dériver d'un singleton, et non des cibles cals. Singleton est un motif. Vous pouvez l'implémenter en tant que classe de modèle (habituellement) ou de classe de base à partir de (rare). classique singleton a:

  • constructeur privé
  • privace copie constructeur
  • destructor privé non virtuel
  • opérateur privé =
  • tient pointeur à l'auto objet
  • a fonction ami externe à obtenir l'objet

Il peut:

  • ont pas mise en œuvre pour cteur, cctor, dtor et oper =, donc essayer de l'appeler de la classe dérivée conduira à une erreur de liaison
  • tirent les enfants privés
  • initialisation objet paresseux
  • ... quoi que ce soit de plus

Il n'y a pas de consensus sur l'implémentation qui est la meilleure et est Singleton bon ou mauvais. À mon avis singleton est plus nocif que utile pour les débutants. Ne l'utilisez pas tant que vous n'en avez pas besoin dans un endroit particulier.

Comme un désert un mauvais modèle Singleton avec des pointeurs intelligents (trouver des erreurs d'horreur!):

#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; 
+0

Merci. Et pour le code, bien que, je ne comprends pas très bien .. Pourriez-vous s'il vous plaît regarder mon code ci-dessus édité et dites-moi pourquoi je reçois l'erreur affichée, et, comment je le réparer? Je vous remercie :)! – Phorce

+0

-1 Pour la mise en œuvre. Retourner un pointeur sur 'T' rend inutile toute la classe' Singleton' car rien ne m'empêche de copier 'T'. En fait, avoir un template singleton est assez inutile, autant faire de la classe originale un singleton. –

+0

@Paul Manta 'trouver des erreurs d'horreur!' Eh bien, vous en avez trouvé un. – Drop

1

Vous devez définir explicitement votre membre statique: Animal *Singleton::pinstance = nullptr;

static Animal* pinstance intérieur de la classe est juste une déclaration , c'est-à-dire qu'aucun espace réel n'est alloué pour la variable. La raison en est que les membres statiques n'appartiennent pas à un objet spécifique et ne sont pas alloués avec l'instance de la classe d'hébergement. Les membres statiques sont partagés le long de toutes les instances de classe et doivent être alloués explicitement.

+0

merci de votre contribution MAIS je l'ai un peu, mais, alors je ne .. J'ai essayé de mettre le Animal * Singleton :: pinstance = null; mais ça ne marche pas! – Phorce

+0

il n'y a pas de 'null', il y a 'nullptr' et vous devez le définir en dehors de la classe, à l'échelle globale. – SomeWittyUsername