web-dev-qa-db-fra.com

Quand devons-nous avoir un constructeur par défaut?

Ma question est simple. Quand devons-nous avoir un constructeur par défaut? Veuillez vous référer au code ci-dessous:

class Shape
{
    int k;

public:
    Shape(int n) : k(n) {}
    ~Shape() {}
};

class Rect : public Shape
{
    int l;

public:
    Rect(int n): l(n)
    {}      //error C2512: 'Shape' : no appropriate default constructor available

    ~Rect() {}
};
  1. Pourquoi le compilateur ne génère-t-il pas implicitement le constructeur par défaut de l'argument zéro dans la classe Rect?

  2. Selon mes connaissances, si une classe (Rect) est dérivée d'une autre classe (Shape) qui a un constructeur par défaut (généré implicitement ou explicitement fourni), le constructeur par défaut doit être généré par le compilateur.

27
XMarshall

Un constructeur par défaut n'est pas synthétisé si vous avez créé votre propre constructeur avec des arguments. Puisque vous avez donné à Shape un constructeur de votre choix, vous devez maintenant écrire explicitement un constructeur Shape par défaut:

class Shape
{
      int k;

  public:
      Shape() : k(0) {}
      Shape(int n) : k(n) {}
      ~Shape() {}
};

(Vous pouvez laisser de côté les définitions de ~Rect() {} vides, car elles seront synthétisées.)

Cependant, il me semble que vous ne voulez pas un constructeur par défaut pour Shape ici. Demandez à Rect de construire correctement la base Shape:

class Shape
{
      int area; // I've had to guess at what this member means. What is "k"?!

  public:
      Shape(const int area)
         : area(area)
      {}
};

class Rect : public Shape
{
     int l;
     int w;

  public:
     Rect(const int l, const int w)
        : Shape(l*w)
        , l(l)
        , w(w)
     {}
};

Notez également que cet exemple est souvent cité comme un abus de OO . Déterminez si vous avez vraiment besoin d'héritage ici.

24

Un constructeur par défaut ne sera généré automatiquement par le compilateur que si aucun autre constructeur n'est défini. Indépendamment de tout héritage.

Et vous devez également construire votre classe de base en appelant:

Rect( int n ) : Shape( n ), l(n)
{
}
11
Nick

Le compilateur définira un ctor par défaut si et seulement si vous ne déclarez explicitement aucun ctor.

Notez que ce qui est important est déclarant le constructeur, pas nécessairement le définissant. Il est assez courant, par exemple, de déclarer un ctor privé, et de ne jamais le définir, pour empêcher le compilateur d'en définir implicitement d'autres.

Edit: Notez également que C++ 11 a un =default syntaxe pour gérer des situations comme la vôtre.

2
Jerry Coffin

Voir ceci pour les comportements complets des constructeurs C++ WRT: http://en.wikipedia.org/wiki/Default_constructor

La réponse simple est que si vous spécifiez un constructeur, le compilateur ne créera pas un constructeur par défaut pour vous.

Cette règle s'applique également à Java.

2
Mike Thomsen

Le constructeur par défaut est généré uniquement si vous n'avez défini aucun autre constructeur.

Soi-disant, si vous avez besoin d'une initialisation spéciale dans la classe, le constructeur par défaut ne ferait pas la bonne chose.

0
Bo Persson

Lorsque vous avez défini un constructeur pour la forme qui attend un entier, vous avez remplacé le constructeur par défaut en procédant ainsi. Donc, si vous étendez Shape, vous devez passer une valeur entière à la superclasse.

0
das_weezul

Le compilateur génère un constructeur par défaut dans le cas où vous n'avez défini aucun constructeur. Mais si vous avez défini un constructeur qui prend ou non un argument. Le compilateur utilisera ce constructeur et ne générera pas de constructeur par défaut avec zéro argument.

0
Sarfraz Ahmed