引用变量延迟绑定

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

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

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. Taurus.MVC 微服务框架 入门开发教程:项目部署:6、微服务应用程序Docker部署实现多开。

    系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 开源地址:https://github.com/cyq1162/Taurus.MVC 本系列第一篇:Tauru ...

  2. fastadmin后台分页设置显示方法

    ​ 1.参照日志列表的分页(后台代码都有) 2.修改默认分页配置,在初始化里面加上: pageList: [5,10,'all'], 3.显示列表: [$where, $sort, $order, $ ...

  3. [双重 for 循环]打印一个倒三角形

    [双重 for 循环]打印一个倒三角形 核心算法 里层循环:j = i; j <= 10; j++ 当i=1时,j=1 , j<=10,j++,打印10个星星 当i=2时,j=2 , j& ...

  4. Pytest fixture及conftest详解

    前言 fixture是在测试函数运行前后,由pytest执行的外壳函数.fixture中的代码可以定制,满足多变的测试需求,包括定义传入测试中的数据集.配置测试前系统的初始状态.为批量测试提供数据源等 ...

  5. Java 自定义Excel数据排序

    通常,我们可以在Excel中对指定列数据执行升序或者降序排序,排序时可依据单元格中的数值.单元格颜色.字体颜色或图标等.在需要自定义排序情况下,我们也可以自行根据排序需要编辑数据排列顺序.本文,将通过 ...

  6. SQL语句中过滤条件放在on、where、having的区别和联系

    摘要:SQL语句中,过滤条件放在不同筛选器on.where和having的区别和联系. 综述   在<SQL语句中过滤条件放在on和where子句中的区别和联系>中,介绍了多表关联SQL语 ...

  7. 查询参数和字符串校验:Query_Parameters_and_String_Validations

    官方文档地址:https://fastapi.tiangolo.com/zh/tutorial/query-params-str-validations/ # -*- coding: UTF-8 -* ...

  8. 解决centos系统突然间网络不通的问题:Global IPv6 forwarding is disabled in configuration, but not currently disabled in kernel

    问题描述:公司里的一台centos 7.6主机,连接公司的路由器,里面设置的静态ip,之前用的好好的,但是有一次突然间ping不通了,之前是可以ping通的. 问题分析: 查看网络配置文件: TYPE ...

  9. [题解] Atcoder Regular Contest ARC 147 A B C D E 题解

    点我看题 A - Max Mod Min 非常诈骗.一开始以为要观察什么神奇的性质,后来发现直接模拟就行了.可以证明总操作次数是\(O(nlog a_i)\)的.具体就是,每次操作都会有一个数a被b取 ...

  10. 整理一些Windows桌面运维常用的命令,并且整合成脚本

    github地址:alittlemc/toy: 编写些脚本将运维经常所用到小玩意所集成在一起 (github.com) 持续更新! 前言 做过桌面运维的大佬们应该可以很明显感受到这份工作所需要的技能不 ...