Come posso cambiare la variabile a cui fa riferimento un riferimento C ++?

Se ho questo:

int a = 2; int b = 4; int &ref = a; 

Come posso fare riferimento a b dopo questo codice?

Questo non è ansible, e questo è di progettazione . I riferimenti non possono essere rimbalzi.

Con C ++ 11 c’è il nuovo (ish) std :: reference_wrapper .

 #include  int main() { int a = 2; int b = 4; auto ref = std::ref(a); //std::reference_wrapper ref = std::ref(a); <- Or with the type specified ref = std::ref(b); } 

Questo è utile anche per memorizzare riferimenti in contenitori.

Non puoi riassegnare un riferimento, ma se stai cercando qualcosa che fornisca capacità simili a questo, puoi invece fare un puntatore.

 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. 

Puoi ottenere o impostare il valore all’interno del puntatore con:

 *ptr = 5; //set int c = *ptr; //get 

Non è ansible riassegnare un riferimento.

Non è ansible nel modo in cui vuoi. C ++ non ti permette di ricolbind ciò a cui fa riferimento un riferimento.

Tuttavia, se vuoi usare l’inganno, puoi quasi simularlo con un nuovo ambito ( non farlo MAI in un programma reale):

 int a = 2; int b = 4; int &ref = a; { int& ref = b; // Shadows the original ref so everything inside this { } refers to `ref` as `b` now. } 

Formalmente parlando, è imansible in quanto è proibito dal design. Arbitrariamente parlando, è ansible.

Un riferimento è memorizzato come puntatore, quindi puoi sempre cambiare dove punta fino a quando sai come ottenere il suo indirizzo. Allo stesso modo, puoi anche cambiare il valore delle variabili const, delle variabili membro const o anche delle variabili membro private quando non hai accesso.

Ad esempio, il codice seguente ha cambiato il riferimento ai membri privati ​​const della class A:

 #include  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=" <
		      	

Puoi creare un wrapper di riferimento molto semplice utilizzando il nuovo posizionamento:

 template< class T > class RefWrapper { public: RefWrapper( T& v ) : m_v( v ){} operator T&(){ return m_v; } T& operator=( const T& a ){ m_v = a; return m_v;} //...... // void remap( T& v ) { //re-map reference new (this) RefWrapper(v); } private: T& m_v; }; int32 a = 0; int32 b = 0; RefWrapper< int > r( a ); r = 1; // a = 1 now r.remap( b ); r = 2; // b = 2 now 

Questo è ansible. Perché sotto il cappuccio, il riferimento è un puntatore. Il seguente codice stamperà “ciao mondo”

 #include "stdlib.h" #include "stdio.h" #include  using namespace std; class ReferenceChange { public: size_t otherVariable; string& ref; ReferenceChange() : ref(*((string*)NULL)) {} void setRef(string& str) { *(&this->otherVariable + 1) = (size_t)&str; } }; void main() { string a("hello"); string b("world"); ReferenceChange rc; rc.setRef(a); printf("%s ", rc.ref.c_str()); rc.setRef(b); printf("%s\n", rc.ref.c_str()); } 

Sebbene sia una ctriggers idea in quanto sconfigge lo scopo di utilizzare i riferimenti, è ansible modificare direttamente il riferimento

 const_cast< int& >(ref)=b;