详解C++引用变量时那些你不知道的东西

 更新时间:2022年11月08日 11:26:45   作者:一条晓鱼ovo  
这篇文章主要为大家详细介绍了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++引用变量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++实现LeetCode(156.二叉树的上下颠倒)

    C++实现LeetCode(156.二叉树的上下颠倒)

    这篇文章主要介绍了C++实现LeetCode(156.二叉树的上下颠倒),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C语言实现阶乘的示例详解

    C语言实现阶乘的示例详解

    在现实中,我们做数学题总会遇到阶乘问题,这在计算机中也不例外。 那我们应该怎么实现呢?下面小编就为大家讲解一下C语言中阶乘的实现
    2022-07-07
  • 排序算法模板实现示例分享

    排序算法模板实现示例分享

    这篇文章主要介绍了排序算法模板实现示例,需要的朋友可以参考下
    2014-03-03
  • Qt进程和线程QProcess和QThread的使用

    Qt进程和线程QProcess和QThread的使用

    本文主要介绍了Qt进程和线程QProcess和QThread的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • C语言循环结构详解

    C语言循环结构详解

    本文主要介绍C语言循环结构的基础知识,这里整理了循环的基础资料并附简单的代码示例详细讲解,有需要的小伙伴可以参考下
    2021-10-10
  • C++检测键盘某键是否按下的方法

    C++检测键盘某键是否按下的方法

    今天小编就为大家分享一篇C++检测键盘某键是否按下的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • 详解C++中String类模拟实现以及深拷贝浅拷贝

    详解C++中String类模拟实现以及深拷贝浅拷贝

    这篇文章主要介绍了详解C++中String类模拟实现以及深拷贝浅拷贝的相关资料,希望通过本文能帮助到大家,让大家实现这样的方法,需要的朋友可以参考下
    2017-10-10
  • c++ 梅森数源码示例解析

    c++ 梅森数源码示例解析

    这篇文章主要为大家介绍了c++ 梅森数源码示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • C++中关于[]静态数组和new分配的动态数组的区别分析

    C++中关于[]静态数组和new分配的动态数组的区别分析

    这篇文章主要介绍了C++中关于[]静态数组和new分配的动态数组的区别分析,很重要的概念,需要的朋友可以参考下
    2014-08-08
  • C语言实现简易三子棋

    C语言实现简易三子棋

    这篇文章主要为大家详细介绍了C语言实现简易三子棋,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07

最新评论