101 votes

Pourquoi les constructeurs ne renvoient-ils pas de valeurs ?

Veuillez me dire pourquoi le constructeur ne renvoie aucune valeur. Je veux une raison technique parfaite pour expliquer à mes étudiants pourquoi le constructeur n'a pas de type de retour.

9 votes

De quelle langue s'agit-il ?

6 votes

Parce qu'il renvoie une instance de la classe. S'il renvoie un type de données, comment allez-vous créer une nouvelle instance ?

0 votes

@Karan Exactement. Les constructeurs renvoient une instance d'une classe, ils ne peuvent donc pas avoir d'autres valeurs de retour.

133voto

Dathan Points 4144

Ce qui se passe en fait avec le constructeur, c'est que le runtime utilise les données de type générées par le compilateur pour déterminer l'espace nécessaire pour stocker une instance d'objet en mémoire, que ce soit sur la pile ou sur le tas.

Cet espace comprend toutes les variables des membres et la vtbl. Une fois cet espace alloué, le constructeur est appelé en tant que partie interne du processus d'instanciation et d'initialisation pour initialiser le contenu des champs.

Ensuite, lorsque le constructeur se termine, le runtime renvoie l'instance nouvellement créée. La raison pour laquelle le constructeur ne renvoie pas de valeur est qu'il n'est pas appelé directement par votre code, mais par le code d'allocation de la mémoire et d'initialisation de l'objet dans le runtime.

Sa valeur de retour (si elle en a une lorsqu'elle est compilée en code machine) est opaque pour l'utilisateur - vous ne pouvez donc pas la spécifier.

0 votes

Pouvons-nous supposer que vous décrivez .NET ?

7 votes

Bien que ce soit techniquement détaillé et correct, un simple "il n'a pas été conçu pour le faire" suffirait, à mon avis. Il ne serait certainement pas impossible de concevoir le runtime pour qu'il renvoie la valeur de retour du constructeur au lieu de l'instance nouvellement créée. Cela n'a tout simplement pas beaucoup de sens et n'a donc pas été conçu pour le faire :)

2 votes

Je ne suis pas certain de l'existence de .Net - ce qui précède est ma compréhension de l'approche adoptée par C++. Je suis sûr que .Net est très similaire, sauf que les métadonnées générées par le compilateur englobent BEAUCOUP plus que la quantité d'espace requise pour l'instancier (et c++ stocke également quelques métadonnées sur le type, mais rien à l'échelle supportée par .Net).

12voto

Thilo Points 108673

Eh bien, d'une certaine manière, il renvoie l'instance qui vient d'être construite.

Vous pouvez même l'appeler comme ça, par exemple en Java.

 Object o = new Something();

ce qui ressemble à l'appel d'une méthode "normale" avec une valeur de retour.

 Object o = someMethod();

2 votes

Alors pourquoi cette méthode ne serait-elle pas autorisée à retourner null ? Je ne suis pas convaincu. Pas du tout.

5 votes

Cela rend l'utilisation du constructeur beaucoup plus facile si vous savez que les seuls états finaux possibles sont "vous avez une instance Something" ou "une exception est levée". (Nous avons essayé de faire en sorte que l'appelant vérifie chaque valeur de retour en C.) Y a-t-il un avantage à avoir deux mécanismes orthogonaux de rapport d'erreur que l'appelant doit vérifier à chaque fois, ou proposez-vous de supprimer également les exceptions ?

4voto

sbi Points 100828

(J'ai un parti pris pour le C++, donc concernant les autres langages, prenez cela avec un grain de sel).

Réponse courte : Vous ne voulez pas avoir à vérifier explicitement le succès de chaque construction d'objet dans votre code.

Réponse un peu plus longue : En C++, les constructeurs sont appelés pour les objets alloués dynamiquement ainsi que pour les objets alloués globalement et automatiquement. Dans ce code

void f()
{
  std::string s;
}

il n'y a aucun moyen pour le constructeur de s ( std::string::string() ) pour retourner une valeur quelconque. Soit il réussit - nous pouvons alors utiliser l'objet, soit il lève une exception - nous n'aurons jamais la chance d'essayer de l'utiliser.

IMO, c'est comme ça que ça devrait être.

4voto

EricSchaefer Points 7592

Comment un constructeur est-il censé renvoyer une valeur de retour ? Le site new renvoie l'instance nouvellement créée. Vous n'appelez pas un ctor, new le fait.

MyClass instance = new MyClass();

Si le ctor devait retourner une valeur, comme ceci :

public int MyClass()
{
    return 42;
}

Où recevriez-vous l'entier ?

0 votes

"Comment un constructeur est censé retourner une valeur de retour ?" Il pourrait retourner this . L'échec de la construction serait indiqué par le retour null .

4 votes

Mais "ceci" doit déjà exister lorsque le constructeur commence à fonctionner. Si votre construction "échoue", le "ceci" est déjà alloué, et alors que se passe-t-il ? Vous avez un objet partiellement construit ? Le destructeur doit-il être appelé ou non ? En C++, si vous lancez le constructeur, vous êtes censé sauvegarder suffisamment d'état dans l'objet zombie pour qu'il puisse nettoyer après lui-même ; sans objet, comment peut-il le faire ? Ou bien avez-vous maintenant 2 mécanismes d'erreur complètement indépendants pour les constructeurs ?

0 votes

@sbi Comme vous n'appelez pas directement la ctro, elle ne peut rien retourner. La référence/pointeur à la nouvelle instance est retournée par new et non le ctor.

2voto

tylerl Points 14541

Lorsque vous appelez un constructeur, la valeur de retour est le nouvel objet :

Point pt = new Point(1,2);

Mais dans le constructeur lui-même, vous ne créez et ne retournez pas réellement l'objet ; il a été créé avant que votre code ne commence, vous ne faites que définir les valeurs initiales.

Point::Point(int x, int y) {
  this->x = x;
  this->y = y;
}

L'absence de type de retour reflète le fait que les constructeurs sont utilisés différemment des autres fonctions. Un type de retour de null bien que techniquement exact, ne reflète pas bien le fait que le code soit utilisé comme s'il retournait un objet. Cependant, tout autre type de retour indiquerait que votre code est censé return quelque chose à la fin, ce qui est également incorrect.

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