37 votes

Problème avec le constructeur C ++

EDIT: Cette question est venu et je pense que j'ai très bien réussi il! Aller StackOverflow!! :D

J'ai des examens à venir, et l'une des questions sur l'année dernière examens était de repérer le problème avec la mise en œuvre de la suite de constructeur et d'écrire un corrigées.

Rectangle::Rectangle(string col, int len, int br)
{
    setColour(col);
    length =len;
    breadth=br;
}

Les définitions de classe sont comme suit:

class Polygon
{
public:
    Polygon(string col="red");
    void printDetails(); // prints colour only
    virtual double getArea()=0;
    void setColour(string col);
private:
    string colour;
};


class Rectangle : public Polygon
{
public:
    Rectangle(string, int, int);
    void printDetails(); // prints colour and area
    // for part 3, delete the line below
    double getArea();
private:
    int length;
    int breadth;
};

J'ai écrit le code dans le compilateur et il fonctionne très bien. Je suppose que la question est relative à la succession, depuis string colour; est privé, mais setColour est public donc je ne peux pas le comprendre. À moins que son Rectangle::Rectangle(string col, int len, int br):length(len), breadth(br) , puis de définir la couleur à l'intérieur de la construcor ou quelque chose.

Sa ne vaut 3 points donc ce n'est pas un gros problème si personne ne veut répondre, mais je me dis que si je vais avoir une carrière en tant que programmeur, son dans mon intérêt d'en savoir autant que possible. ;)

Merci pour toute aide.

PS, reportez - getArea() en Rectangle. Quand je le supprimer il me dit qu'il "ne peut pas instancier la classe abstraite". Qu'est-ce que cela signifie?

EDIT: Voici les principaux:

void main (void)
{
    Rectangle rect1 ("blue",5,6);
    Rectangle *prect2 = new Rectangle("red",5,6);
    rect1.setColour("red");
    rect1.printDetails();
    prect2->printDetails();
}

23voto

J T Points 2333

Je ne vois rien de mal, si vous pourriez le rendre plus efficace en utilisant une liste d'initialisation (sinon le privé, les membres des deux classes de l'initialisation des deux fois):

Rectangle::Rectangle(string col, int len, int br) 
: Polygon(col), length(len), breadth(br)
{

}

Notez que la liste d'initialisation peut appeler le constructeur de Polygone ainsi.

Voir Pourquoi je préfère utiliser la liste d'initialisation de membre? pour une description complète des avantages de l'utilisation de l'initialisation des listes.

10voto

Laurynas Biveinis Points 6305

S'il s'agit des meilleures pratiques C ++, alors:

  1. Passer les paramètres de chaîne par référence const;
  2. Utilisez la liste d'initialisation et initialisez la couleur en la transmettant au constructeur parent, et non à setColour.

9voto

rerun Points 15285

La seule chose que je vois d'emblée est qu'il existe deux printDetails () mais que la classe de base n'est pas virtuelle, vous ne risquez donc pas d'obtenir le comportement polymorphe attendu.

7voto

T.E.D. Points 26829

Le principal "problème", je vois (et c'est un peu mineur), c'est que la dérivée constructeur permet au parent de la classe de l'utilisation par défaut de colo(u)r ("rouge"), puis fournit son propre. C'est un peu du gaspillage, quand vous pourriez avoir donné le bon à partir de l'obtenir-aller.

Rectangle::Rectangle(string col, int len, int br) : Polygon(col) {
    length =len;
    breadth=br;
};

Maintenant, après avoir fait le ci-dessus, vous pouvez initialiser tous les membres de cette façon:

Rectangle::Rectangle(string col, int len, int br) 
    : Polygon(col), length(len), breadth(br) {};

Hmmm. Maintenant que je regarde ça, il y a une autre chose de mal avec elle. Votre constructeur sont de passage en std::string objets par copie, et de ne pas les modifier. C'est un gaspillage de trop. Tous le constructeur string paramètres doit être changé à l' string const & paramètres. Cela peut éviter une copie supplémentaire de la construction d'une chaîne à l'exécution, et en informe le compilateur et les utilisateurs que vous n'êtes pas réellement la modification de l'entrée des chaînes (ce qui est bien pratique quand vous en réalité ne le sont pas).

De sorte que la version finale serait ressembler à:

Rectangle::Rectangle(string const & col, int len, int br) 
    : Polygon(col), length(len), breadth(br) {};

Cette formulation vous prend de 4 std::string constructions (et 3 destructions) pour chaque Rectangle constructeur appelé à 2. Il peut être pris vers le bas pour un en faisant le même changement à l' Polygon constructeur.

6voto

Stormenet Points 8695

Vous devriez appeler le constructeur de base avec le paramètre col:

 Rectangle::Rectangle(string col, int len, int br) : Polygon(col)
{
    //setColour(col);
    length =len;
    breadth=br;
}
 

En ce qui concerne la getArea () :
La raison pour laquelle il ne compile pas lorsque vous le supprimez est due au fait que cette fonction est marquée comme virtuelle pure dans votre classe Polygon virtual double getArea()=0; à l'aide de =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