web-dev-qa-db-fra.com

Combien de constructeurs la classe a-t-elle?

Je me prépare pour un prochain examen C++ et suis tombé sur cette question concernant les classes et les constructeurs:

Combien de constructeurs possède la classe Fraction? "

class Fraction {
//...
public:
   Fraction(int numerator = 0, int denominator = 1);
//...
};

Je pensais que ce n'était qu'un, mais ils ont suggéré qu'il y en avait trois:

Fraction();
Fraction(n);
Fraction(n, d);

Ou en d'autres termes:
ne fonction avec des valeurs par défaut est-elle une fonction surchargée?

57

Il n'y a qu'un seul constructeur correspondant à la déclaration publiée, pas trois surcharges.

Les appels

Fraction();
Fraction(n);

sont équivalents à:

Fraction(0, 1);
Fraction(n, 1);

Une autre façon de vous convaincre qu'il n'y a qu'un seul constructeur correspondant à la déclaration est que vous n'avez besoin de définir qu'un seul constructeur, pas trois.

La section de la norme C++ 11 sur les arguments par défaut a ceci:

8.3.6 Arguments par défaut

1 Si une clause d'initialisation est spécifiée dans une déclaration de paramètre , ceci la clause d'initialisation est utilisée comme argument par défaut. Les arguments par défaut seront utilisés dans les appels où les arguments de fin sont manquants.

2 [ Exemple: la déclaration

void point(int = 3, int = 4);

déclare une fonction qui peut être appelée avec zéro, un ou deux arguments de\type int. Il peut être appelé de l'une des manières suivantes:

point(1,2); point(1); point();

Les deux derniers appels sont équivalents à point(1,4) et point(3,4), respectivement. - exemple de fin ]

Maintenant, la question principale.

Combien de constructeurs possède la classe Fraction?

Si la personne qui a formulé la question souhaite inclure le constructeur de déplacement et le constructeur de copie, qui sont implicitement générés par le compilateur, sauf suppression explicite, dans l'ensemble des constructeurs, alors la réponse est trois. Dans ce cas, la question est une question piège.

55
R Sahu

ne fonction avec des valeurs par défaut est-elle une fonction surchargée?

Les surcharges ressemblent

Fraction();
Fraction(int numerator);
Fraction(int numerator, int denominator);

et ont chacun leur propre implémentation (définition), tandis qu'une fonction avec des paramètres par défaut a une seule implémentation.


Je pensais que ce n'était qu'un, mais ils ont suggéré qu'il y en avait 3: ...

"Combien de constructeurs possède la classe Fraction?"

C'est une question piège, conçue pour vous tromper en montrant les variantes d'appel disponibles pour une déclaration constructeur unique.

La réponse définitive pour l'extrait de code donné est (en mots trois).

Il existe un constructeur spécialisé (qui sert trois variantes d'appel), et le compilateur génère automatiquement un constructeur de copie et de déplacement si vous ne les delete, ou ne fournissez pas d'implémentation personnalisée:

Fraction(int numerator = 0, int denominator = 1); // (1)
// Redundant, just for demonstration:
Fraction(const Fraction& rhs) = default; // (2)
Fraction(Fraction&& rhs) = default; // (3)

Donc, pour un tel examen, si vous répondez

La classe a un constructeur

C'est faux de toute façon. Si vous répondez

La classe a trois constructeurs (comme vous l'avez écrit, c'est la réponse acceptée)

vous devrez expliquer en détail pourquoi vous pensez que oui (comme expliqué ci-dessus).
Dans tout examen oral, je vous demanderais de sauvegarder pourquoi exactement, donc je le ferais dans un test d'apprenti.

27

La réponse à votre question est relative à ces trois questions de suivi:

  1. Avant C++ 11, C++ 11 ou C++ 14 et au-delà?
  2. Les constructeurs définis implicitement comptent-ils?
  3. Quels sont les membres? La présence d'un membre non copiable supprimera le constructeur de copie implicite.

La définition explicite n'est qu'un constructeur; le compilateur insère un appel à trois arguments, que l'appel fournisse explicitement 0, 1 ou 2 arguments.

Dans pré-'11, il n'y a pas de constructeurs de mouvement, dans '11, il y a deux définitions implicites de constructeurs, Fraction(const Fraction &) noexcept et Fraction(Fraction &&) noexcept, vérifiez l'accessible cppreference , in '14 les règles du moment où il y a un changement de constructeur de mouvement défini implicitement.

La question que vous vous posez est malheureusement innocente mais assez technique; J'espère que votre classe n'insiste pas sur une simplification excessive du C++, c'est la pire façon de l'apprendre.

18
TheCppZoo

Vous n'avez qu'une seule déclaration d'un constructeur.
D'un autre côté:

Lorsque deux ou plusieurs déclarations différentes sont spécifiées pour un seul nom dans la même étendue, ce nom est dit surchargé

Pour cette raison, je n'utiliserais pas le terme surchargé ici.

5
skypjack