0
#include <iostream> 

class Bar 
{ 
    protected: 

public: 
     int & x; 
     Bar(int & new_x) 
     :x(new_x) 
     {} 
     Bar & operator = (const Bar toCopy) 
     { 
      x = toCopy.x; 
      return *this; 
     } 
}; 

int main() 
{ 
    int x1(1); 
    int x2(2); 

    Bar bar = Bar(x1); 
    std::cout << bar.x << std::endl; 

    bar = Bar(x2); 
    std::cout << bar.x << std::endl; 

    bar.x = 5; 
    std::cout << bar.x << std::endl; 

    std::cout << x1 << std::endl; 
    std::cout << x2 << std::endl; 

} 

La sortie est:écrit `` = opérateur de référence pour les membres non-statique classe

1 
2 
5 
5 
2 

Ce que je suis en train de faire est copiex et enregistrez dans l'objet bar.

La sortie me suggère que l'opérateur d'affectation n'a pas fait sa magie, à la fois en termes de en copiant et en prenant la valeur du nouvel objet. J'ai suivi this link.

La modification de x en une valeur plutôt qu'une référence n'est pas possible, car dans le vrai programme x est une classe abstraite.

S'il vous plaît, si possible, s'abstenir d'utiliser l'affectation de tas.

EDIT: 1. J'ai réalisé que je viens d'abattre le langage C++. Je voudrais m'excuser auprès de tous les ordinateurs parlant "C++ ian". Ma motivation était d'assigner une variable abstraite membre sur la pile. Autant que je comprends, il ne peut pas être fait sur la pile, parce que la taille de la classe dérivée n'est pas connue à la compilation. 2. OK ... Je suis un total n00b ... (non sh * t, Sherlock!). "Programmation C++ efficace" @rhalbersma est un must have. Il contient des éléments essentiels, mais vous ne les trouverez nulle part (copier des constructions, initialiser la copie), .. en un seul endroit de toute façon.

+3

données de référence publiques, en passant des arguments par référence non const ou valeur const: vous pouvez commencer à lire Effective C++ ou similaire pour obtenir vos membres de classe de base à droite. – TemplateRex

+0

Je n'utilise jamais de références en tant que membres, j'utilise plutôt des pointeurs, vous pouvez tout faire (initialiser le pointeur avec & new_x par exemple) et plus encore. Certaines personnes aiment les références en tant que membres en raison de leur limitation ... –

Répondre

1

Les références peuvent être source de confusion. Donc peut const pointeurs. Je vais essayer d'éclaircir les choses en parlant des deux en même temps. Que puis-je dire, je suis un optimiste.

D'abord, const pointeurs.

Nous allons commencer par une classe appelée Foo. Nous pouvons avoir un pointeur vers cette classe - un Foo*. Nous pouvons avoir un pointeur vers une instance const de cette classe - un Foo const*. Et nous pouvons avoir un pointeur const à une instance non const de cette classe - un Foo*const.

Un Foo const* est un pointeur peut modifier les données que vous ne pouvez pas modifier.

Un Foo*const est un pointeur que vous ne pouvez pas modifier en données peut changer.

Je suppose que vous avez cela. Je suis, après tout, un optimiste. Ensuite, regardons les références.

Il est vrai que les références sont des alias, il est parfois utile de penser à eux dans un monde où les choses ont mises en œuvre concrètes en termes d'autres types.

Un Foo& est analogue à un Foo*const - un « pointeur » non modifiable à une instance de Foo vous pouvez changer. Donc, le Foo dont vous parlez est toujours le même, mais vous pouvez changer son état.

Maintenant, c'est un peu plus que ça. Il y a du sucre syntaxique. Lorsque vous créez une référence à une autre variable, elle exécute automatiquement le &. Par conséquent, lorsque vous effectuez une opération Foo& f = a;, cette opération est analogue à Foo*const f = &a;. Deuxièmement, lorsque vous utilisez ., il fait la même chose que -> dans le cas du pointeur. Troisièmement, lorsque vous faites une assignation, elle ne peut évidemment pas changer la valeur du pointeur - parce que c'est const - mais à la place elle change la valeur de la chose pointée. Donc Foo& f = a; a = b; fait l'équivalent de Foo*const f = &a; *f = b;.

Il attribue la chose a souligné, plutôt que le pointeur, lorsque vous utilisez operator=. Mais lorsque vous l'initialisez, il n'utilise pas operator=, même si vous avez un jeton =.

L'initialisation est différente de l'affectation en général, et la sémantique de ce qui se passe avec une référence & et un pointeur * dans l'initialisation et l'affectation est très différente.

Foo& f = a; f = b; fait deux choses complètement différentes. L'initialisation d'une référence initialise la partie "const pointeur" - l'affectation à une référence modifie la chose pointée sur. Mon nom personnel pour la façon dont l'initialisation et l'affectation signifient différentes choses avec des références est «sémantique de référence», par opposition à «sémantique de pointeur» où l'initialisation et l'affectation changent la chose pointée. Dans la «sémantique de référence», l'initialisation sélectionne la chose pointée et l'affectation change l'état de la chose pointée.

Ceci est très confus, et j'espère que j'ai contribué à le rendre confus d'une manière différente.

3

Bar bar = Bar(x1); n'est pas d'affectation, mais copie-initialisation. Il appelle le constructeur de copie, pas l'opérateur d'affectation de copie. Le problème est que vous ne comprenez pas la référence - le membre Bar::x est juste un alias pour une autre variable. L'assignation de quelque chose va également modifier l'original.

+0

la référence n'est pas mon premier choix, mais je dois contourner le fait que dans mon vrai programme x est un type de classe abstraite – aiao

+3

@aiao utiliser un pointeur intelligent alors, pas une référence. –

0

Le x intérieur bar est la même variable que celui qui est appelé "x1" dans main.
C'est ce que les références font - elles prennent une variable et lui donnent un autre nom que vous pouvez utiliser pour vous y référer.
Quoi que vous fassiez pour cette variable sous ce nouveau nom est la même chose que de le faire sous un autre nom.

D'abord, sur le côté droit après

Bar bar = Bar(x1); 

(qui est l'initialisation de copie, pas d'affectation)
« bar.x » fait référence à la même variable que « x » dans l'objet anonyme, qui à son tour est un nom différent pour "x1" dans main. Par la suite, le nom "bar.x" fait référence à la même variable que le nom "x1".

La ligne

bar = Bar(x2); 

attribue la valeur (à savoir, 2) de l'objet anonyme de x, qui est la même variable que x2, à la variable que l'on appelle « x » à l'intérieur bar, mais dont le nom est "x1" dans main.

La ligne

bar.x = 5; 

attribue alors la valeur 5 à la variable dont le nom est « bar.x » qui, encore une fois, est la même variable « x1 » dans principal.

Vous ne pouvez pas faire référence à une variable différente.
Si vous voulez quelque chose qui peut faire référence à différentes variables, vous devez utiliser un pointeur.

Questions connexes