引用变量延迟绑定

我们知道引用变量定义时要立刻赋值,告诉编译器他是谁的引用.如果不赋值,编译会失败.

如果引用变量是单个定义的,对他赋值还比较简单.

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++ 关于引用变量你不知道的东西的更多相关文章

  1. C++引用变量学习

    版权所有,转载请注明来源 (1)reference variable(rv) 主要用处是作为方程的形式参数,使用rv 可以直接对原数据进行操作而不是该数据的拷贝,节省了时间和空间,尤其是对于结构体以及 ...

  2. Java基础-被final修饰的引用变量的指向

    final修饰的引用变量一旦初始化赋值之后就不能再指向其他的对象,那么该引用变量指向的对象的内容可变吗?看下面这个例子: public class Test { public static void ...

  3. PHP GC垃圾回收机制之引用变量回收周期疑问

    普通的引用变量的销毁大家都知道, 当unset的时候如果refcount = 0 则认为无用, 销毁. 但是手册中提到一点会有递归引用的问题,很是奇葩 代码如下 <?php $a = 1; $a ...

  4. C++引用变量(转)

    引用变量 c++中引用变量的使用: 定义: int rate=80; int  & pt=rate 1.pt 是引用变量,申明引用变量时必须将其初始化.pt 和rate 的值指向相同的内存变量 ...

  5. c#问答篇:对象与引用变量-----初学者的困惑

    转自:http://www.cnblogs.com/huangyu/archive/2004/08/02/29622.html 从宏观的角度来看,对象是类的实例.比如: //定义一个名为Someone ...

  6. C++ primer(八)--内联函数 引用变量 引用传递函数参数 函数重载/模板/模板具体化

    一.内联函数     常规函数和内联函数的区别在于C++编译器如何将他们组合到程序中.编译过程的最终产品是可执行程序--由一组机器语言指令组成.运行程序时,操作系统将这些指令载入到计算机内存中,因此每 ...

  7. C++学习笔记29,引用变量(1)

    引用变量在创建的时候就必须初始化.无法创建一个未被初始化的引用. #include <iostream> using namespace std; int main() { int x=1 ...

  8. [DB][mybatis]MyBatis mapper文件引用变量#{}与${}差异

    MyBatis mapper文件引用变量#{}与${}差异 默认,使用#{}语法,MyBatis会产生PreparedStatement中.而且安全的设置PreparedStatement參数,这个过 ...

  9. PHP关于foreach使用引用变量的坑

    写PHP好多年,但仍然会犯低级错误,今天遇到个 foreach中引用变量时的坑,PHP版本为 5.6.12 代码如下: <?php $arr = ['a', 'b', 'c', 'd', 'e' ...

随机推荐

  1. vscode 插件 Cnblogs Client For VSCode

    目录 简介 主要功能 登录 / 授权 将本地 markdown 文件发布到博客园 博客园博文列表 将本地文件关联到博客园博文 拉取远程博文内容更新本地文件 图片上传 博文分类管理 导出 pdf 博文设 ...

  2. HDU 6222 Heron and His Triangle (pell 方程)

    题面(本人翻译) A triangle is a Heron's triangle if it satisfies that the side lengths of it are consecutiv ...

  3. python数据精度问题

    一.python运算时精度问题: 1.运行时精度问题在Python中(其他语言中也存在这个问题,这是计算机采用二进制导致的),有时候由于二进制和十进制之间对应问题会导致数值的精度问题,比如无法用有限个 ...

  4. 用metasploit映射公网远程控制舍友电脑

    用metasploit映射公网远程控制舍友电脑 Metasploit是一款开源的安全漏洞检测工具,可以帮助安全和IT专业人士识别安全性问题,验证漏洞的缓解措施,并管理专家驱动的安全性进行评估,提供真正 ...

  5. KingabseES 锁机制

    KingabseES的锁机制 目录 KingabseES的锁机制 一.前言 二.锁机制 三.表级锁 ( Table-Level Locks ) 1.访问共享(ACCESS SHARE) 2.行共享(R ...

  6. kingbaseES R6 读写分离集群修改ssh端口案例

    数据库环境: test=# select version(); version ------------------------------------------------------------ ...

  7. SpringBoot Xml转Json对象

    一.导入需要的依赖 <dependency> <groupId>maven</groupId> <artifactId>dom4j</artifa ...

  8. JAVA中容器设计的进化史:从白盒到黑盒,再到跻身为设计模式之一的迭代器

    大家好,又见面了. 在我们的项目编码中,不可避免的会用到一些容器类,我们可以直接使用List.Map.Set.Array等类型.当然,为了体现业务层面的含义,我们也会根据实际需要自行封装一些专门的Be ...

  9. 在云原生中监控JVM指标

    一般 Java 集成 Prometheus 监控指标有两种方式.一种是依赖中引入,另外一种是通过agent执行. 依赖引入 <!-- The client --> <dependen ...

  10. kibana知识点

    1.Kibana 有 Linux.Darwin 和 Windows 版本的安装包.由于 Kibana 基于 Node.js 运行,我们在这些平台上包含了一些必要的 Node.js 二进制文件.Kiba ...