Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

*this ou this

9 réponses
Avatar
Aziz
Bonjour,

Je voudrais savoir pourquoi le type retourne n'est pas simplement un
pointeur.

Date& Date::add_year(int n)
{
/* ... */

return *this;
}

Est-ce qu'il est faux de retourner this au lieu de *this?

Merci.


PS: Stroustrup, TC++PL p.231

9 réponses

Avatar
Matthieu Moy
Aziz writes:

Bonjour,


Bonjour,

Je voudrais savoir pourquoi le type retourne n'est pas simplement un
pointeur.

Date& Date::add_year(int n)


C'est une référence (à cause du &).

Ca a a peu près la sémantique d'un pointeur, c'est à dire que tu peux
avoir plusieurs références vers le même objet, mais avec la syntaxe
d'une variable normale. (Et les mêmes règles de typage tant que tu n'a
pas de const)

Concrêtement, l'objet retourné te permettra de modifier l'objet *this
comme si tu avais renvoyé un pointeur.

{
/* ... */

return *this;
}

Est-ce qu'il est faux de retourner this au lieu de *this?


Tu auras un problème de typage si tu le fais.

--
Matthieu

Avatar
Loïc Joly
Aziz wrote:

Bonjour,

Je voudrais savoir pourquoi le type retourne n'est pas simplement un
pointeur.

Date& Date::add_year(int n)
{
/* ... */

return *this;
}



Exemple d'utilisation (comme je ne connais pas cette classe, j'invente
la syntaxe) :

Date maDate(16, AOUT, 1974);
maDate.addYear(1).addMonth(6); // 18 mois
// Et version "je retourne un date*"
maDate.addYear(1)->addMonth(6);
// Pas très homogène...

// Pire encore
int duree = maDate.addYear(15).addDay(1) - autreDate.addMonth(8);
// deviendrait avec un retour pointeur :
int duree = *(maDate.addYear(15)->addDay(1)) - *(autreDate.addMonth(8));


Est-ce qu'il est faux de retourner this au lieu de *this?


Avec cette déclaraton, oui.

Avatar
Horst Kraemer
On Mon, 26 Apr 2004 14:19:22 +0300, Aziz
wrote:

Bonjour,

Je voudrais savoir pourquoi le type retourne n'est pas simplement un
pointeur.

Date& Date::add_year(int n)
{
/* ... */

return *this;
}

Est-ce qu'il est faux de retourner this au lieu de *this?


Le retour d'une référence à un objet équivaut à l'initialisation de la
valeur de retour avec un objet, c.a.d. à


Date myDate;
Date &retval = myDate;

Donc il faut retourner un objet du type Date "en personne" et non un
pointeur parce qu'il faut initialiser une référence à Date par un
objet du type Date en non par un pointeur vers Date.

Une autre explication: Un pointeur vers Date et une référence à Date
sont des notions tout à fait différentes. Un pointeur est quelque
chose qui pointe vers un objet, donc il est un objet lui-même. Une
référence n'est ni un objet ni une valeur. elle est simplement un nom
pour un objet. Il n'a pas de sens d'initialiser un nom par un
pointeur. Quand Date::add_year(int) retourne une référence à Date cela
veut dire que tu peux utiliser l'expression


myDate.add_year(1)

comme si elle était une variable du type Date (en fait cette
expression *est* myDate après l'addition). Il est donc parfaitement
logique qu'il faut initialiser quelque chose qui représente un objet
du type Date par un objet du type Date et non par un pointeur vers
Date.

--
Horst

Avatar
Aziz
Merci beaucoup pour les reponses...
Avatar
Boris Sargos
Salut,

moi je n'ai pas compris ta réponse Horst. Pourquoi ne pas écrire :

Date* Date::addyear(int n) {
/* ... */
return this;
}

Merci Horst.


Le retour d'une référence à un objet équivaut à l'initialisation de la
valeur de retour avec un objet, c.a.d. à


Date myDate;
Date &retval = myDate;

Donc il faut retourner un objet du type Date "en personne" et non un
pointeur parce qu'il faut initialiser une référence à Date par un
objet du type Date en non par un pointeur vers Date.

Une autre explication: Un pointeur vers Date et une référence à Date
sont des notions tout à fait différentes. Un pointeur est quelque
chose qui pointe vers un objet, donc il est un objet lui-même. Une
référence n'est ni un objet ni une valeur. elle est simplement un nom
pour un objet. Il n'a pas de sens d'initialiser un nom par un
pointeur. Quand Date::add_year(int) retourne une référence à Date cela
veut dire que tu peux utiliser l'expression


myDate.add_year(1)

comme si elle était une variable du type Date (en fait cette
expression *est* myDate après l'addition). Il est donc parfaitement
logique qu'il faut initialiser quelque chose qui représente un objet
du type Date par un objet du type Date et non par un pointeur vers
Date.

--
Horst



Avatar
Horst Kraemer
On Mon, 26 Apr 2004 23:35:26 +0200, "Boris Sargos"
wrote:

Salut,

moi je n'ai pas compris ta réponse Horst. Pourquoi ne pas écrire :

Date* Date::addyear(int n) {
/* ... */
return this;
}


Tu peux écire cela. Mais ta question concernait la fonction

Date& Date::addyear(int n) {
/* ... */
return *this;
}

Peut-etre tu as posé une mauvaise question et tu voulais savoir
pourquoi on préfère

Date& Date::addyear(int n) {
/* ... */
return *this;
}

à

Date* Date::addyear(int n) {
/* ... */
return this;
}


Je retourne la question. Quel est l'intérêt de retourner un pointeur
vers l'objet pour lequel tu appelles la fonction addyear au lieu de
retourner l'objet lui-même, c.a.d. pourquoi veux-tu que

myDate.addyear(1)

soit un pointeur vers myDate au lieur de myDate "en personne" ? Avec
la version proposée tu pourrais écrire

myDate.addyear(1).f1().f2();

si f1 et f2 sont aussi des fonctions membres qui retournent *this,
p.ex.

myDate.addyear(1).addyear(3).addyear(4);
// exemple théorique

Avec la deuxième version tu devrais écrire

myDate.addyear(1)->addyear(3)->addyear(4);

Quelle version est plus "naturelle" ?

--
Horst

Avatar
Horst Kraemer
On Mon, 26 Apr 2004 23:35:26 +0200, "Boris Sargos"
wrote:

Salut,

moi je n'ai pas compris ta réponse Horst. Pourquoi ne pas écrire :

Date* Date::addyear(int n) {
/* ... */
return this;
}


Je retourne la question. Quel est l'intérêt de retourner un pointeur
vers l'objet pour lequel tu appelles la fonction addyear au lieu de
retourner l'objet lui-même, c.a.d. pourquoi veux-tu que

myDate.addyear(1)

soit un pointeur vers myDate au lieu de myDate "en personne" après la
modification par la fonction addyear ? Avec la version proposée tu
pourrais écrire

myDate.addyear(1).f1().f2();

si f1 et f2 sont aussi des fonctions membres qui retournent *this,
p.ex.

myDate.addyear(1).addyear(3).addyear(4);
// exemple purement théorique

Avec la deuxième version tu devrais écrire

myDate.addyear(1)->addyear(3)->addyear(4);

Quelle version est plus "naturelle" ?

--
Horst

Avatar
Boris Sargos
Je suis d'accord avec toi. Il est plus simple d'utiliser des références.
Mais je constate que la version pointeur n'est pas fausse.
Merci.

"Horst Kraemer" a écrit dans le message de
news:
On Mon, 26 Apr 2004 23:35:26 +0200, "Boris Sargos"
wrote:

Salut,

moi je n'ai pas compris ta réponse Horst. Pourquoi ne pas écrire :

Date* Date::addyear(int n) {
/* ... */
return this;
}


Je retourne la question. Quel est l'intérêt de retourner un pointeur
vers l'objet pour lequel tu appelles la fonction addyear au lieu de
retourner l'objet lui-même, c.a.d. pourquoi veux-tu que

myDate.addyear(1)

soit un pointeur vers myDate au lieu de myDate "en personne" après la
modification par la fonction addyear ? Avec la version proposée tu
pourrais écrire

myDate.addyear(1).f1().f2();

si f1 et f2 sont aussi des fonctions membres qui retournent *this,
p.ex.

myDate.addyear(1).addyear(3).addyear(4);
// exemple purement théorique

Avec la deuxième version tu devrais écrire

myDate.addyear(1)->addyear(3)->addyear(4);

Quelle version est plus "naturelle" ?

--
Horst




Avatar
Twxs

si f1 et f2 sont aussi des fonctions membres qui retournent *this,
p.ex.

myDate.addyear(1).addyear(3).addyear(4);
// exemple purement théorique

Avec la deuxième version tu devrais écrire

myDate.addyear(1)->addyear(3)->addyear(4);

Quelle version est plus "naturelle" ?



et si dans le code on se retrouve avec un pointeur sur Date

myDate_ptr->addyear(1).addyear(3).addyear(4);

*versus*

myDate_ptr->addyear(1)->addyear(3)->addyear(4);

Quelle version est plus "naturelle" ?

trop dure la vie ;-)

Twxs