c++ 关于引用变量你不知道的东西
引用变量延迟绑定
我们知道引用变量定义时要立刻赋值,告诉编译器他是谁的引用.如果不赋值,编译会失败.
如果引用变量是单个定义的,对他赋值还比较简单.
struct test_T
{
int data;
//...其他成员
test_T(int _data = 0) :data(_data){}
};
struct SaveTest
{
test_T & ref;
//...其他成员
SaveTest(test_T & _ref) :ref(_ref){}
};
int main(void)
{
test_T *t = new test_T[2];
SaveTest *s = new SaveTest[2]{t[0], t[1]};
for (int i = 0; i < 2; i++){
t[i].data = i + 1;
}
for (int i = 0; i < 2; i++){
printf("%d ", s[i].ref.data);
}
return 0;
}
如果数组很大.就不方便了.不方便用{}一个一个赋值了.
struct test_T
{
int data;
//...其他成员
test_T(int _data = 0) :data(_data){}
};
struct SaveTest
{
test_T & ref;
//...其他成员
SaveTest(test_T & _ref) :ref(_ref){}
};
int main(void)
{
test_T *t = new test_T[2000];
SaveTest *s = new SaveTest[2000];//没有用{},编译直接报错
for (int i = 0; i < 2000; i++){
t[i].data = i + 1;
}
for (int i = 0; i < 20; i++){
printf("%d ", s[i].ref.data);
}
return 0;
}
我的想法是:先要骗过编译器,调用SaveTest构造函数的时候先赋个默认值,真正的我们用的对象
引用,后面再慢慢赋值给它.
struct test_T
{
int data;
//...其他成员
test_T(int _data = 0) :data(_data){}
};
//******************************增加全局唯一默认值
test_T default_test(-1);
//******************************
struct SaveTest
{
test_T & ref;
//...其他成员 修改构造函数
SaveTest(test_T & _ref = default_test) :ref(_ref){}
};
int main(void)
{
test_T *t = new test_T[2000];
SaveTest *s = new SaveTest[2000];//编译ok
for (int i = 0; i < 10; i++){
t[i].data = i + 1;
s[i].ref = t[i];//重新赋值
}
for (int i = 0; i < 10; i++){
printf("%d ", s[i].ref.data);
}
return 0;
}
输出:
怎么会这样???.(我现在还是不理解)
通过上面的方式,可以做到延迟赋值,但是赋值很奇怪,单个可以被修改,但是所有成员的ref都会一
起被更改,真是秀儿~.
行,那就只能换个思路了.引用不能延迟赋值,指针类型可以吧,我用指针类型.
struct test_T
{
int data;
//...其他成员
test_T(int _data = 0) :data(_data){}
};
//******************************全局唯一默认值
test_T default_test(-1);
//******************************
struct SaveTest
{
test_T * ref;
//...其他成员
SaveTest(test_T * _ref = nullptr) :ref(_ref){}
};
int main(void)
{
test_T *t = new test_T[2000];
SaveTest *s = new SaveTest[2000];//编译ok
for (int i = 0; i < 10; i++){
t[i].data = i + 1;
s[i].ref = &t[i];//重新赋值
}
for (int i = 0; i < 10; i++){
printf("%d ", s[i].ref->data);
}
return 0;
}
哼~,可以了吧.
等一下,等一下,跑题了,虽然这样做可以,但是不是用的引用实现的啊.
练剑的最高境界就是无剑胜有剑,达到人剑合一,剑既是我,我既是剑.
是时候,让指针跟引用合二为一啦.
struct test_T
{
int data;
//...其他成员
test_T(int _data = 0) :data(_data){}
};
union MyUnion
{
test_T * ptr;
test_T & ref;
MyUnion(){}
};
struct SaveTest
{
MyUnion u;
//...其他成员
SaveTest(test_T& _ref){
u.ptr = &_ref;
}
void set(test_T& _ref){
u.ptr = &_ref;
}
test_T& get(){
return u.ref;
}
};
int main(void)
{
test_T *t = new test_T[2000];
SaveTest *s = new SaveTest[2000];//编译ok
for (int i = 0; i < 10; i++){
t[i].data = i + 1;
s[i].set(t[i]);//重新赋值
}
for (int i = 0; i < 10; i++){
printf("%d ", s[i].get().data);
}
return 0;
}
使用者角度:
SaveTest *s = new SaveTest[2000];//只是定义变量,没有绑定
s[i].set(t[i]);//第一次具体赋值,绑定引用(站在使用者角度看)
s[i].get();//得到一个引用
内部:
每次保存的都是指针,每次使用的时候用引用.
从汇编角度,引用和指针,本是一家.
还有,上面那个问题,有兴趣的可以试一下,交流交流.
c++ 关于引用变量你不知道的东西的更多相关文章
- C++引用变量学习
版权所有,转载请注明来源 (1)reference variable(rv) 主要用处是作为方程的形式参数,使用rv 可以直接对原数据进行操作而不是该数据的拷贝,节省了时间和空间,尤其是对于结构体以及 ...
- Java基础-被final修饰的引用变量的指向
final修饰的引用变量一旦初始化赋值之后就不能再指向其他的对象,那么该引用变量指向的对象的内容可变吗?看下面这个例子: public class Test { public static void ...
- PHP GC垃圾回收机制之引用变量回收周期疑问
普通的引用变量的销毁大家都知道, 当unset的时候如果refcount = 0 则认为无用, 销毁. 但是手册中提到一点会有递归引用的问题,很是奇葩 代码如下 <?php $a = 1; $a ...
- C++引用变量(转)
引用变量 c++中引用变量的使用: 定义: int rate=80; int & pt=rate 1.pt 是引用变量,申明引用变量时必须将其初始化.pt 和rate 的值指向相同的内存变量 ...
- c#问答篇:对象与引用变量-----初学者的困惑
转自:http://www.cnblogs.com/huangyu/archive/2004/08/02/29622.html 从宏观的角度来看,对象是类的实例.比如: //定义一个名为Someone ...
- C++ primer(八)--内联函数 引用变量 引用传递函数参数 函数重载/模板/模板具体化
一.内联函数 常规函数和内联函数的区别在于C++编译器如何将他们组合到程序中.编译过程的最终产品是可执行程序--由一组机器语言指令组成.运行程序时,操作系统将这些指令载入到计算机内存中,因此每 ...
- C++学习笔记29,引用变量(1)
引用变量在创建的时候就必须初始化.无法创建一个未被初始化的引用. #include <iostream> using namespace std; int main() { int x=1 ...
- [DB][mybatis]MyBatis mapper文件引用变量#{}与${}差异
MyBatis mapper文件引用变量#{}与${}差异 默认,使用#{}语法,MyBatis会产生PreparedStatement中.而且安全的设置PreparedStatement參数,这个过 ...
- PHP关于foreach使用引用变量的坑
写PHP好多年,但仍然会犯低级错误,今天遇到个 foreach中引用变量时的坑,PHP版本为 5.6.12 代码如下: <?php $arr = ['a', 'b', 'c', 'd', 'e' ...
随机推荐
- 以太坊 layer2: optimism 源码学习(二) 提现原理
作者:林冠宏 / 指尖下的幽灵.转载者,请: 务必标明出处. 掘金:https://juejin.im/user/1785262612681997 博客:http://www.cnblogs.com/ ...
- 造数字(数位DP)
题面 JZM 想要创造两个数字 x 和 y,它们需要满足 x or y = T,且Lx ≤ x ≤ Rx, Ly ≤ y ≤ Ry,JZM 想知道 x and y 有多少种可能的不同的取值.若有多组 ...
- 【Java】学习路径57-TCP协议客户端与服务器端的关闭
在TCP协议中,如果发送端(客户端)关闭了,那么接收端(服务器端)端就会收到这个消息. 那么接收端(服务器端)怎么知道的呢? 我们进行实验: 首先在发送端中编写一段程序,当用户输入"end& ...
- kubeadm部署k8s v1.19.4版本集群
1. 准备2台2c4g虚机 配置地址192.168.198.144,192.168.198.146,一台作为master,一台作为node 2. 部署环境准备,每一台虚机都需要操作 # 关闭防火墙sy ...
- KingbaseES R6 集群通过备库clone在线添加新节点
案例说明: KingbaseES R6集群可以通过图形化方式在线添加新节点,但是在添加新节点clone环节时,是从主库copy数据到新的节点,这样在生产环境,如果数据量大,将会对主库的网络I/O造成压 ...
- 利用ldt_struct 与 modify_ldt 系统调用实现任意地址读写
利用ldt_struct 与 modify_ldt 系统调用实现任意地址读写 ldt_struct与modify_ldt系统调用的介绍 ldt_struct ldt是局部段描述符表,里面存放的是进程的 ...
- 我的 Kafka 旅程 - Linux下的安装 & 基础命令
准备工作 安装解压缩工具 tar # 检查是否安装了解压缩工具 tar yum list tar # 如未安装 tar yum install tar -y 安装必备的 java # 检查是否安装了 ...
- Kubernetes 日志:搭建 EFK 日志系统
Kubernetes 中比较流行的日志收集解决方案是 Elasticsearch.Fluentd 和 Kibana(EFK)技术栈,也是官方现在比较推荐的一种方案. Elasticsearch 是一个 ...
- docker垃圾处理
1 查找docker文件夹 find / -name docker 2 列举文件夹大小 du -h --time --max-depth=1 . df -h df -TH 3 Docker占用磁盘空间 ...
- 清除已安装的rook-ceph集群
官方文档地址:https://rook.io/docs/rook/v1.8/ceph-teardown.html 如果要拆除群集并启动新群集,请注意需要清理的以下资源: rook-ceph names ...