什么是引用

引用变量是已定义变量的别名。

如何定义引用变量:

  int rats;

  int & rodents = rats;

其中&不失地址运算符,而是类型标识符的一部分。就行声明char*是指的是指向char的指针一样。

int &指的是指向int的引用。

引用看起来和指针很类似,但是还是不太一样的。

很重要一点:引用必须在声明引用时将其初始化!!

int rat;

int & rodents;

rodent =rat;  // 这样是错误的;

为什么要这样规定?

这是因为引用其实是一个const指针;const变量的特点就是在声明的时候当然得初始化啦,一旦初始化完毕就不能修改。

也就是说引用一旦跟某个变量关联起来,就一直效忠于它,在引用变量的整个生命周期里。是不是很专一?

所以:int & rodents =rats;

实际上是以下代码的伪装表示:

int * const pr =&rats;

引用可以用来做什么?

1)引用可以用来做函数的参数

 void swapr(int & a, int & b)
{
int temp;
temp = a;
a = b;
b = temp;
}

当使用按引用传递参数的时候,类似于按指针传递参数(C++中大多用按引用传递取代按指针传递了)。

函数的形参可以直接对原始变量(实参)进行操作了,而不是在函数中产生原始变量实体的副本。

一般按值传递参数时,要给形参分配内存空间,形参变量就是原始变量(实参)的副本。

对于大块数据而言,按值传递的内存开销比较大,效率也比较低下。

而采用按址传递(按引用和按指针)可以避免大块的数据全部压入栈中。

2)常引用

在普通引用定义前面加一个只读标识符const。

 double refcube(const double & ra)
{
return ra * ra * ra;
}

这样做的目的是可以定义一个变量的只读别名,而不用担心变量的值被别名意外地改掉。

3)引用作为函数返回值

为什么要返回引用?答案:效率会更高!

返回引用和传统返回机制的不同之处;

double m = sqrt(16.0);

cout << sqrt(25.0);

第一条语句中,值4.0被复制到一个临时位置,然后被复制给m。

在第二天语句中,值5.0倍复制到一个临时位置,然后被传递给cout

dup = accumulate(team,five);

如果accumulate()返回一个结构,而不是指向结构的引用,将把整个结构复制到一个临时位置,再将这个拷贝复制给dup。

但在返回值为引用时,将直接把team复制到dup,其效率更高。

引用作为函数返回值时需要注意:

const free_throws & clone2(free_throws & ft)
{
free_throws newguy; //first step to big error
newguy =ft;
return newguy;
}

  不能返回指向局部变量的引用,局部变量在被调用函数返回后就被销毁掉了。那么它返回的引用所指向的内存已经没有任何意义,运行时会出现不可预知的错误。所以以上代码是错误的。

正确的操作如下:

 free_throws & accumulate(free_throws & target, const free_throws & source)
{
target.attempts += source.attempts;
tartget.made += source.made;
set_pc (target);
return target;
}

有的时候为了避免在设计中添加模糊的特性,因为模糊的特性增加的犯错的机会。

所以还可以将返回类型声明为const引用。返回类型是不可修改的左值,以下语句就不合法了:

accumulate(dup, five) = four;  //not allowed

C++_引用变量探究的更多相关文章

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

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

  2. C++第四篇--重载_指针_引用

    C++第四篇--重载_指针_引用 1. 基础知识 重载:函数名相同,根据参数不同(类型.数量.顺序不同)调用同名函数 指针和引用:引用就是别名,引用时必须初始化,引用你定义的变量. int a; in ...

  3. Java千百问_05面向对象(011)_引用传递和值传递有什么差别

    点击进入_很多其它_Java千百问 1.什么是值传递 值传递,是将内存空间中某个存储单元中存放的值,传送给还有一个存储单元.(java中的存储单元并不是物理内存的地址,但具有相关性) 比如: //定义 ...

  4. Don’t Use Accessor Methods in Initializer Methods and dealloc 【初始化和dealloc方法中不要调用属性的存取方法,而要直接调用 _实例变量】

    1.问题:    在dealloc方法中使用[self.xxx release]和[xxx release]的区别? 用Xcode的Analyze分析我的Project,会列出一堆如下的提示:Inco ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. hadoop再次集群搭建(2)-配置免秘钥ssh登录

    SSH对于大多程序员都不陌生,目前主流的云服务提供上也是通过SSH来提供链接的安全保障,比如AWS通过使用下载的私钥(private key)实现与EC2实例安全连接.GitHub通过上传的公钥(pu ...

  2. 【转】Sublime Text2中的快捷键一览表(Sublime 键盘快捷键大全 )

    Sublime Text 提供了无比强大的快捷键阵容,如果能够在Coding的时候灵活的使用快捷键,将能够使得你的效率倍增,相信在不久的将来,Sublime Text将是你跨平台使用的最佳Coding ...

  3. C run-time函数总览

    Argument Access(参数访问):变长参数列表.这个模块提供了三个宏:va_arg.va_end和va_start,用来实现变长参数列表的访问. Buffer Manipulation(内存 ...

  4. android 中context的具体作用和意义

    context在android中是非常重要的一个类,此类一般用于activity之中 从字面意思来看,这是环境变量,内部实现了一些方法,但是此类也可以看做是一个句柄,用来唯一标示activity 举个 ...

  5. 奇葩问题 eclipse下 maven项目 java Resource报个小红叉,然而里面却没有小红叉

    之前没注意,不知是一开始就有还是这两天才有,说下解决方案: 右击项目“Properties”,在弹出的“Properties”的左侧边框,单击“Project Facets”,打开“Project F ...

  6. MyBatis配置Setting详细说明

    该表格转载自http://blog.csdn.net/summer_yuxia/article/details/53169227 setting是指定MyBatis的一些全局配置属性,这是MyBati ...

  7. SpringBoot09 自定义servlet、注册自定义的servlet、过滤器、监听器、拦截器、切面、webmvcconfigureradapter过时问题

    1 servlet简介 servlet是一种用于开发动态web资源的技术 参考博客:servlet基础知识     httpservlet详解 2 在springboot应用中添加servlet sp ...

  8. Selenium二次封装-Python版本

    from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from seleni ...

  9. session跨域共享

    www.maxomnis.com的index.php文件内容 <?phpsession_start();setcookie("user", "alex proter ...

  10. EZOJ #77

    传送门 分析 一个比较神奇的思路 我们考虑分治,对于每一个区间[le,ri]我们计算这个区间中左端点属于[le,mid],右端点属于[mid+1,ri]的情况对答案的贡献 我们求左半个区间的最大最小值 ...