Tar*_*aru 63 c++ reference dynamic-rebinding
如果我有这个:
int a = 2;
int b = 4;
int &ref = a;
Run Code Online (Sandbox Code Playgroud)
如何在此代码后ref
引用b
?
Dav*_*hop 71
使用C++ 11,有新的(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);
}
Run Code Online (Sandbox Code Playgroud)
这对于在容器中存储引用也很有用.
Joh*_*0te 19
你不能重新分配一个引用,但是如果你正在寻找能够提供相似功能的东西,你可以改为使用指针.
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.
Run Code Online (Sandbox Code Playgroud)
您可以使用以下命令获取或设置指针中的值:
*ptr = 5; //set
int c = *ptr; //get
Run Code Online (Sandbox Code Playgroud)
这不可能以你想要的方式.C++只是不允许你重新绑定引用指向的内容.
但是,如果你想使用技巧,你几乎可以使用新的范围来模拟它(永远不要在真实程序中这样做):
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.
}
Run Code Online (Sandbox Code Playgroud)
从形式上讲,这是不可能的,因为它被设计禁止.任意地说,这是可能的.
引用存储为指针,因此只要您知道如何获取其地址,就可以始终更改它指向的位置.同样,当您无权访问时,您还可以更改const变量,const成员变量甚至私有成员变量的值.
例如,以下代码更改了类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'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;
}
Run Code Online (Sandbox Code Playgroud)
节目输出:
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
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,a.i1最初指向i,在更改之后,它指向j.
但是,这样做被认为是危险的,因此不推荐,因为它违背了数据封装和OOP的最初目的.它更像是内存地址黑客攻击.
归档时间: |
|
查看次数: |
51778 次 |
最近记录: |