Si j'ai ça :
int a = 2;
int b = 4;
int &ref = a;
Comment puis-je faire ref
se référer à b
après ce code ?
Si j'ai ça :
int a = 2;
int b = 4;
int &ref = a;
Comment puis-je faire ref
se référer à b
après ce code ?
Ce n'est pas possible, et c'est par le design . Les références ne peuvent pas être rebondies.
Dans le code ci-dessous, je change la référence de x en k et j'obtiens toujours le résultat. Pouvez-vous me dire comment cela est possible ? int a=50 ; int &x=a ; int k=10 ; cout<<x<<endl ; x=k ; cout<<x<<endl ;
Avec C++11, il y a le nouveau (ou presque) std::reference_wrapper .
#include <functional>
int main() {
int a = 2;
int b = 4;
auto ref = std::ref(a);
//std::reference_wrapper<int> ref = std::ref(a); <- Or with the type specified
ref = std::ref(b);
}
Ceci est également utile pour stocker des références dans des conteneurs.
Vous ne pouvez pas réassigner une référence, mais si vous cherchez quelque chose qui offre des capacités similaires à celle-ci, vous pouvez utiliser un pointeur à la place.
int a = 2;
int b = 4;
int* ptr = &a; //ptr points to memory location of a.
ptr = &b; //ptr points to memory location of b now.
Vous pouvez obtenir ou définir la valeur du pointeur avec :
*ptr = 5; //set
int c = *ptr; //get
D'un point de vue formel, c'est impossible car c'est interdit par la conception. Arbitrairement parlant, c'est possible.
Une référence est stockée sous la forme d'un pointeur, de sorte que vous pouvez toujours changer l'endroit où elle pointe tant que vous savez comment obtenir son adresse. De même, vous pouvez modifier la valeur des variables const, des variables membres const ou même des variables membres privées lorsque vous n'y avez pas accès.
Par exemple, le code suivant a modifié la référence du membre privé const de la classe A :
#include <iostream>
using namespace std;
class A{
private:
const int &i1;
public:
A(int &a):i1(a){}
int geti(){return i1;}
int *getip(){return (int*)&i1;}
};
int main(int argc, char *argv[]){
int i=5, j=10;
A a(i);
cout << "before change:" << endl;
cout << "&a.i1=" << a.getip() << " &i=" << &i << " &j="<< &j << endl;
cout << "i=" << i << " j=" <<j<< " a.i1=" << a.geti() << endl;
i=6; cout << "setting i to 6" << endl;
cout << "i=" << i << " j=" <<j<< " a.i1=" << a.geti() << endl;
*(int**)&a = &j; // the key step that changes A's member reference
cout << endl << "after change:" << endl;
cout << "&a.i1=" << a.getip() << " &i=" << &i << " &j="<< &j << endl;
cout << "i=" << i << " j=" <<j<< " a.i1=" << a.geti() << endl;
j=11; cout << "setting j to 11" << endl;
cout << "i=" << i << " j=" <<j<< " a.i1=" << a.geti() << endl;
return 0;
}
Sortie du programme :
before change:
&a.i1=0x7fff1b624140 &i=0x7fff1b624140 &j=0x7fff1b624150
i=5 j=10 a.i1=5
setting i to 6
i=6 j=10 a.i1=6
after change:
&a.i1=0x7fff1b624150 &i=0x7fff1b624140 &j=0x7fff1b624150
i=6 j=10 a.i1=10
setting j to 11
i=6 j=11 a.i1=11
Comme vous pouvez le constater a.i1 indique initialement i Après le changement, il pointe vers j .
Toutefois, cette pratique est considérée comme dangereuse et donc déconseillée, car elle va à l'encontre de l'objectif initial de l'encapsulation des données et de la POO. Il s'agit plutôt d'un piratage d'adresse mémoire.
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.