基本用法

我们还是从具体的代码出发,那种陈腐的传值、传指针、传引用之间的区别不再赘述,任何一本C语言的书中都有详细的例子:

int x = 10, y = 20;
int& refX = x;          // 引用必须依附对象而存在,必须与合法的内存单元相关联// 引用(refX)是变量(x)的别名(alias)// 对引用(refX)的全部操作等价于对所关联变量(x)的的操作
refX = y;   // 将y的值赋值给refX,也就是赋值给x// 而不是修改refX的指向使其指向y// C++不允许将reference改指向不同对象// refX一日指向x,就终身指向x,绝不三心二意,朝三暮四
cout << "refX = "<< refX << ", x = " << x << endl;      // 20 20

上述代码反映在内存单元中:

我们继续理解C++不允许让reference改指向不同对象

也就是怎么修改引用的值都可以,但就是不可以修改其地址或者让其指向另外一个对象。

int x = 10, y = 20;
int& refX = x;
&refX = &y;         // 错误:表达式必须是可修改的左值(left value)
int x = 10, y = 20;
int& refX = x;
int& refY = y;
refX = refY;            // 将refY所指向的y的值赋给refX,也即是赋给x
refY = 30;              // 修改y的引用refY的值,也即是修改修改y的值
cout << "refX = " << refX << ", x = " << x << endl;     // 20 20
cout << "refY = " << refY << ", y = " << y << endl;     // 30 30

同理,我们可类推其他类型数据相互引用的例子:

string s1("hello"), s2("world");
string& refS1 = s1;
string& refS2 = s2;
refS1 = refS2;
refS2 = "China";
cout << "refS1 = " << refS1 << ", s1 = " << s1 << endl;// refS1 = "world", s1 = "world"
cout << "refS2 = " << refS2 << ", s2 = " << s2 << endl;// refS2 = "China", s2 = "China"

作为类的成员变量时

上一节的易混淆之处还好明白,陷阱还较容易避免。当引用作为一个类的成员函数存在且与赋值运算符(operator=)相结合的时候,就比较不容易发现问题了,我们认为地构造一个以string类型作为成员变量的类:

class Student
{
public:Student(string& name):_name(name){}// 这里必须以引用作为参数进行传递,// 如果是值语义的话,// 成员变量最终得到的是一个局部对象的引用// 而这个局部对象会在构造函数退出时,被销毁// 既然引用所指向的对象都不存在了,自然
private:string& _name;
}int main(int, char**)
{// Student stu1("zhang");    // 错误,类型不匹配,"zhang"是const char[6]Student stu1(string("zhang"));Student stu2(string("li"));stu1 = stu2;     // 错误,operator=不可用// C++不允许让reference改指向不同的对象return 0;
}

解决方案之一

将成员变量从引用语义,改变为值语义

解决方案之二

重写赋值运算符(operator=):

class Student
{
public:Student(string& name):_name(name){}Student& operator=(const Student& rhs){_name = rhs._name;return *this;}
private:string& _name;
}

关于向参数类型分别为stringstring&的函数传递字符数组时可能发生的类型退化等更有趣更详尽的讨论出门左转请参阅<C++基础——使用字符串作为函数模板的实参>

C++基础——有关引用的问题相关推荐

  1. 【转载】C ++ 基础 指针 引用

    基础不扎实 >_<! C++中传值参数和引用参数怎样区别呢? 看以下例子: #include<iostream> using namespace std; void swap( ...

  2. java 静态内部类 弱引用_Java基础 强引用、弱引用、软引用、虚引用

    前言 在ThreadLocal源码中,其中嵌套类ThreadLocalMap中的Entry继承了WeakReferenc.Java中提供这四种引用类型主要有两个目的:第一是可以让程序员通过代码的方式决 ...

  3. Java 7之基础 - 强引用、弱引用、软引用、虚引用

    2019独角兽企业重金招聘Python工程师标准>>> 1.强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.如下 ...

  4. 弱引用什么时候被回收_Java基础 强引用、弱引用、软引用、虚引用

    前言 在ThreadLocal源码中,其中嵌套类ThreadLocalMap中的Entry继承了WeakReferenc.Java中提供这四种引用类型主要有两个目的:第一是可以让程序员通过代码的方式决 ...

  5. [Java基础]方法引用

    代码如下: package PrintablePack;public interface Printable {void printString(String s);} package Printab ...

  6. C++学习基础篇 —— 引用()的用法和应用

    一.引用简介 引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样. 引用的声明方法:类型标识符&引用名=目标变量名: [例1]: [cpp] view plaincopy ...

  7. WB8使用说明-基础(引用)

    1.静态引用链接: 通过设置如下属性来来静态引用CSS和JS cssLinks : Array 需要在页面中引用的css链接列表.该属性仅在首页或在iframe中运行的模块内有效,内置模块页面引用cs ...

  8. java基础-----弱引用,软引用,强引用,虚引用

    转自:http://www.cnblogs.com/blogoflee/archive/2012/03/22/2411124.html 1.概述 在JDK1.2以前的版本中,当一个对象不被任何变量引用 ...

  9. Java基础_引用数据类型的强制类型转换

    在Java中由于继承和向上转型,子类可以非常自然地转换成父类,但是父类转换成子类则需要强制转换.因为子类拥有比父类更多的属性.更强的功能,所以父类转换为子类需要强制.那么,是不是只要是父类转换为子类就 ...

最新文章

  1. 解析目标检测全流程!附代码数据
  2. APK 本地化和去广告
  3. 动态获取UILabel的bounds
  4. 从近两年的CVPR会议来看,目标检测的研究方向是怎么样的?
  5. 杭电1421java实现
  6. 视频创作助力企业营销
  7. Vue — 第七天(vue-cli-案例)
  8. 本地配置_Hadoop本地模式的安装配置
  9. C语言代码规范(三)if语句
  10. Android画板控件,可以写字,签名,画画并生成图片
  11. 容器精华问答 | 我们为什么需要容器?
  12. vue-cli本地的一个websocket
  13. 奥鹏刷分软件_【中国大学mooc刷课系统和奥鹏在线作业自动答案软件哪个好用】中国大学mooc刷课系统和奥鹏在线作业自动答案软件对比-ZOL下载...
  14. 笔记本电脑装android系统安装教程,电脑上安装Android 10小白教程,大屏Android用起来...
  15. 苹果手机显示没有连接服务器怎么办啊,苹果手机更新连接到服务器出现问题怎么办...
  16. pyecharts 十种图形演示
  17. 【Java Set接口】
  18. python文件有几种类型、分别是什么_4. 内置类型
  19. 饮用水铁离子超标,各种溶液铁离子超标去除工艺
  20. 每天听一本书,日精日进

热门文章

  1. cvi调用matlab dll,cvi通过artix调用matlab
  2. thinkpython2e电子书下载_《Think Python 2e》中译版电子书分享
  3. 在Navicat中修改表结构
  4. matlab查找指定文件夹下文件(附汉字和标点符号读取方法)
  5. 将数据集转换为Excel格式的一个实现
  6. 数据挖掘:数据清洗——数据不平衡处理
  7. numpy之meshgrid和where(转)
  8. the android emulator process,Android studio报错:The emulator process for AVD (xxx) was killed
  9. bootstrap不同分辨率显示滚动条_bootstrap基础快速入门-8 响应式显示与隐藏
  10. 汇编笔记-DOSBox安装和使用