How to change the variable the C ++ link refers to?

If I have this:

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

How can I make ref reference to b after this code?

+43
c ++ reference
Oct 10 '11 at 13:12
source share
9 answers

This is not possible, and by design . Links cannot be restored.

+57
Oct 10 '11 at 13:15
source share

With C ++ 11 there is a new (ish) 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); } 

It is also useful for storing links in containers.

+45
Nov 27 '13 at 4:01
source share

You cannot reassign the link, but if you are looking for something that provides similar capabilities, you can make a pointer instead.

 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. 

You can get or set the value inside the pointer with:

 *ptr = 5; //set int c = *ptr; //get 
+15
Oct. 10 '11 at 13:26
source share

You cannot reassign the link.

+7
Oct 10 '11 at 13:16
source share

This is not possible at your request. C ++ simply does not allow you to reinstall what the link refers to.

However, if you want to use trickery, you can almost imitate it using a new area (NEVER do this in a real program):

 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. } 
+7
Oct 10 '11 at
source share

Formally speaking, this is not possible, since it is prohibited by design. Generally speaking, this is possible.

Links are stored as a pointer, so you can always change where it points, as long as you know how to get its address. Similarly, you can also change the value of constant variables, constant member variables, or even private member variables when you do not have access.

For example, the following code changed the reference to class A const:

 #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 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; } 

Program output:

 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 

As you can see, a.i1 initially points to i, after changing it points to j.

However, this is considered dangerous and therefore not recommended, as it defeats the original goal of encapsulating data and OOP. This is more like a memory hack.

+4
Sep 16 '15 at 10:57
source share

You can make the link shell very easy using the new placement:

 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 
+3
Mar 28 '14 at 10:31
source share

It is possible. Because under the hood, the link is a pointer. The following code will print "hello world"

 #include "stdlib.h" #include "stdio.h" #include <string> 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()); } 
+3
May 21 '15 at 2:04
source share

Although its a bad idea, since it defeats the purpose of using links, you can directly change the link

 const_cast< int& >(ref)=b; 
0
Mar 19 '14 at 19:32
source share



All Articles