J'ai récemment vu une question sur le débordement de pile sur la façon d'obtenir un objet dérivé à partir d'une fonction,
certains ont suggéré de créer un objet local et de renvoyer une copie de la fonction. Que diriez-vous de renvoyer ce
à partir de la fonction?
Je veux juste savoir, est-ce une bonne pratique de codage?
Merci pour votre aide et votre temps.
Voici mon exemple de code.
class Base { public: virtual ~Base() {} }; class Derived: public Base { private: int i; public: Derived* func(int e) { i = e; return this; } int getI() { return i; } };
3 Réponses :
Vous pouvez utiliser votre code comme ceci
Derived x(123); Derived* x_ptr = &x;
Cela semble plus facile d’écrire ceci (en supposant un constructeur approprié)
Derived d; Derived* d_ptr = d.func(123);
Mais peut-être vous pensiez à autre chose.
la question à laquelle je faisais référence posée sur le débordement de pile était de créer un objet sans utiliser de nouvel opérateur
Vous pouvez renvoyer une copie de l'objet tant que son constructeur de copie n'est pas privé ou protégé: Derived func () {... return Derived ();}
. Si aucun constructeur de copie ou de déplacement n'a été défini, ou des constructeurs appropriés définis, alors le compilateur optimisera probablement cela en un déplacement.
@DNT vous remercie vraiment utile. comment accepter vos réponses sont toutes utiles
@VenkataCharyPadala Vous créez des objets en déclarant des variables, ou en utilisant le constructeur pour créer des temporaires (comme le suggère DNT).
Derived d; Derived* d_ptr = d.func(123); why not d_ptr = &d; whey d.func returns thisï¼ when use d.func, user have the pointer of d. no need to return again. may be want to use in chain like d.funcï¼1ï¼->func(2)->func(3)
Plusieurs opérateurs utilisés pour renvoyer l'auto-référence (mais pas le pointeur):
opérateur + =
, opérateur - =
, ... principalement pour imiter le comportement intégré.
Cela permet d'enchaîner l'opération: a = b = c = 42;
(au lieu de c = 42; b = c; a = b;
).
(Abuser de) le chaînage n'est pas nécessairement plus lisible, et la division en plusieurs instructions peut être plus claire.
Le pro-chaînage l'applique également au setter:
rectangle.set_height(42).set_width(21).set_position(x, y);
A propos du pointeur par rapport à la référence, renvoyer le pointeur implique généralement que nullptr
est une valeur possible (sinon référence est mieux).
Les opérateurs qui peuvent renvoyer un pointeur sont (adresse de) opérateur &
et flèche operator->
.
Comportement de &
par défaut renvoie déjà this
, donc pas besoin de le surcharger pour renvoyer this
.
operator- >
devrait, à la fin, renvoyer un pointeur; ce
peut être un choix valide en fonction de la classe de wrapper.
Cela renverrait un pointeur vers le
Derived
existant. Est-ce ce que vous avez l'intention?en fait, je veux savoir est-ce une bonne pratique ou avons-nous des effets secondaires en faisant cela?
Il n'y a pas d'effets secondaires, mais vous avez le problème que vous avez toujours avec les pointeurs, qui est de vous assurer que l'objet pointé dure au moins aussi longtemps que le pointeur. En d'autres termes, vous ne vous retrouvez pas avec un pointeur suspendu.
Ceci est utilisé dans certains cas pour les interfaces de classe «fluent», mais en C ++ il existe des références qui rendent les interfaces fluentes beaucoup plus lisibles. Avec un retour de pointeur, vous pouvez écrire
obj.Derived () -> getI () 'mais si le type de retour était
Derived & `à la place et que le retour étaitreturn * this;
, alors vous pouvez écrireobj.Derived (). getI ()
@DNT Je comprends que, nous pouvons renvoyer cela à partir de la fonction, et je vois la différence, vous parlez, merci.