113 votes

Quelles sont les utilisations pratiques d'un constructeur protégé ?

Pourquoi déclarer un constructeur protégé ? Je sais que les constructeurs sont déclarés privés dans le but de ne pas permettre leur création sur la pile.

6voto

sean riley Points 1520

Pour les méthodes d'usine avec des effets secondaires.

class mine {

  private:
    mine () {};

  protected:
    mine(int id) : m_id(id) {};

   int m_id;
   static int m_count;

  public:
    static mine* CreateOneOfMe() {
         return mine(m_count++);
    }

    int GetId() { return m_id; }

 };

Cela crée des instances de la classe et garantit que chacune d'entre elles possède un identifiant unique incrémentiel. Notez que si le constructeur que vous voulez utiliser n'est pas celui par défaut, vous devez également cacher ce dernier.

1 votes

Vous pouvez également ne pas déclarer le constructeur par défaut et il n'existera pas.

4voto

Oliver Hanappi Points 5141

Pour permettre à une sous-classe d'utiliser un constructeur qui ne doit pas être accessible directement à un instanciateur.

3voto

Vous pourriez l'utiliser pour limiter les classes qui pourraient le créer, par exemple :

class Level
{
private:

 Level();
 ~Level();

 friend class LevelManager;
};

La seule classe qui peut en créer une instance est la classe LevelManager. Vous saurez donc toujours que l'instance Level est créée dans le LevelManager.

1 votes

Bien que cela soit vrai, c'est un constructeur privé, pas protégé.

1voto

bigdata2 Points 626

Une utilisation du constructeur protégé est de mettre en œuvre le modèle CRTP, voir le code ci-dessous :

#include <iostream>
#include <assert.h>

template <class T>
class ComparableMixin {
public:
    bool operator !=(ComparableMixin &other) {
        return ~(*static_cast<T*>(this) == static_cast<T&>(other));
    }
    bool operator <(ComparableMixin &other) {
        return ((*(this) != other) && (*static_cast<T*>(this) <= static_cast<T&>(other)));
    }
    bool operator >(ComparableMixin &other) {
        return ~(*static_cast<T*>(this) <= static_cast<T&>(other));
    }
    bool operator >=(ComparableMixin &other) {
        return ((*static_cast<T*>(this) == static_cast<T&>(other)) || (*(this) > other));
    }
protected:
    ComparableMixin() {}
};

class Integer: public ComparableMixin<Integer> {
public:
 Integer(int i) {
     this->i = i;
 }
 int i;
 bool operator <=(Integer &other) {
     return (this->i <= other.i);
 }
 bool operator ==(Integer &other) {
     return (this->i == other.i);
 }
};
int main() {

    Integer i(0) ;
    Integer j(1) ;
    //ComparableMixin<Integer> c; //compilation error!
    assert (i < j );
    assert (i != j);
    assert (j >  i);
    assert (j >= i);

    return 0;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X