C++引用的一篇不完全总结

1、引用基础

引用是为对象起了另一个名字,通常将声明符写成"&d"的形式来定义引用类型,其中d是声明的变量名:

int ival = 1024;
int &refVal = ival;
引用必须初始化,引用并非对象,只是已经存在的对象的另一个名字而已。定义了一个引用以后,对其进行的所有操作都是在与之绑定的对象上进行的:

refVal = 2;
int ii = refVal;
引用本身不是对象,所以不能定义引用的引用

本文地址: http://wuyudong.com/2016/11/10/2971.html ,转载请注明出处。

2、指向指针的引用

因为引用本身不是对象,所以自然没有指向引用的指针,但是指针是对象,所有可以定义指针的引用:

int i = 1;
int *p;
int *&r = p; //r是一个对指针p的引用
r = &i;      //r引用了一个指针,即是p指向i
*r = 0;      //解引用r得到i
3、const的引用

可以把引用绑定到const对象上,成为对常量的引用,对常量的引用不能被用作修改它所绑定的对象:

const int ci = 1024;
const int &r1 = ci;
r1 = 42;    //error:r1是对常量的引用
int &r2 = ci;    //error:试图让一个非常量引用指向一个常量对象
初始化常量引用时允许用任意表达式作为初始值,前提是该表达式的结果能转换成引用的类型即可,尤其为一个常量引用绑定非常量的对象、字面值,甚至一个一般的表达式:

int i = 42;
const int &r1 = i;
const int &r2 = 42;
const int &r3 = r1 * 2;
int &r4 =  r1 * 2;    //error:r4是一个普通的非常量引用
4、函数传引用参数

通过引用形参,允许函数改变一个或多个实参的值

void reset(int &i)
{
    i = 0;
}
int j = 23;
reset(j);
cout<<"j = "<<j<<endl;  //j = 0
技巧1:使用引用避免拷贝

拷贝大的类类型对象或者容器对象比较低效,甚至有的类类型(包括IO类型在内)根本就不支持拷贝操作,这时候就可以通过引用形参访问该类型的对象,举个例子:

bool isShorter(const string &s1, const string &s2)
{
    //string 对象可能会非常长,选择引用
    return s1.size() < s2.size();
}
技巧2:使用引用形参返回额外信息

如果有的时候函数需要返回多于一个值,引用参数为这种需求提供了可能。

举个例子:实现一个函数,返回string对象中某个指定字符第一次出现的位置,同时返回该字符出现的总次数

string::size_type find_char(const string &s, char c, string::size_type &occurs)
{
    auto ret = s.size();
    occurs = 0;
    for(decltype(ret) i = 0; i != s.size(); i++) {
        if(s[i] == c) {
            if(ret == s.size()) {
                ret = i;
            }
            occurs++;
        }
    }
    return ret;
}
auto index = find_char(s, c, occurs)
5、数组引用形参

C++允许将变量定义成数组的引用,这样,形参可以是数组的引用,此时,引用形参绑定到对应的实参上,也就是绑定到数组上:

void print(int (&array)[10])
{
    for(auto elem : array)
        cout<<elem<<endl;
}
int k[10] = {0,1,2,3,4,5,6,7,8,9};
print(k);
6、函数返回引用

如果函数返回引用,则该引用仅是它所引用对象的一个别名,举个例子:

const string &shorterString(const string &s1, const string &s2)
{
    return s1.size() <= s2.size() ? s1 : s2;
}
其中形参和返回结果均是const string的引用,这样无论调用函数还是返回结果都不会真正拷贝string对象。

调用一个返回引用的函数将得到左值,其他返回类型得到右值,这样我们就能为返回类型是非常量引用的函数的结果赋值:

char &get_val(string &s, string::size_type i)
{
    return s[i];
}

int main()
{
    string s("a bug!");
    cout<<s<<endl;  //输出:a bug
    get_val(s, 0) = 'A';
    cout<<s<<endl; //输出:A bug
    system("PAUSE");
    return 0;
}
本文总结了在c++中引用的各种用法,以后接着补充。

时间: 2024-10-17 08:55:09

C++引用的一篇不完全总结的相关文章

ASP实现上一篇,下一篇过程代码

ASP实现上一篇,下一篇过程代码 Rem==上一篇== Rem====================================================== Rem= 参数说明: Rem= pid当前ID,prame:栏目前辍(如一般web_news表,字段时一般为wn_**,prame就代表wn) Rem= ptable(表前辍.如一般表名是:站点名_表名(shenzhe_news) ptable:就代表shenzhe) Rem= 说明:采用上面命名法,可使该过程达到通用 Rem

上一篇,下一篇过程代码

过程 Rem==上一篇==Rem================================================================Rem= 参数说明:Rem= pid当前ID,prame:栏目前辍(如一般web_news表,字段时一般为wn_**,prame就代表wn)Rem= ptable(表前辍.如一般表名是:站点名_表名(shenzhe_news) ptable:就代表shenzhe)Rem= 说明:采用上面命名法,可使该过程达到通用Rem==========

iOS闭包循环引用精讲

前言 本篇文章精讲iOS开发中使用Block时一定要注意内存管理问题,很容易造成循环引用.本篇文章的目标是帮助大家快速掌握使用block的技巧. 我相信大家都觉得使用block给开发带来了多大的便利,但是有很多开发者对block内存管理掌握得不够好,导致经常出现循环引用的问题.对于新手来说,出现循环引用时,是很难去查找的,因此通过Leaks不一定能检测出来,更重要的还是要靠自己的分析来推断出来. 声景一:Controller之间block传值 现在,我们声明两个控制器类,一个叫ViewContr

Android JNI局部引用表溢出:local reference table overflow (max=512)

转载请注明出处:http://blog.csdn.net/xyang81/article/details/44873769 在<JNI/NDK开发指南(十)--JNI局部引用.全局引用和弱全局引用>这篇文章中详细介绍了在JNI中三种引用的使用方式,区别.应用场景和开发注意事项.由于都是理论,看完之后可能印象不够深刻,由其是在开发当中容易出错的地方.所以这篇文章用一个例子说明引用使用不当会造成的问题,以引起大家对这个知识点的重视. 首先创建一个Android工程,在主界面放一个文本框和一个按钮,

上一篇,下一篇过程代码_应用技巧

复制代码 代码如下: Rem==上一篇==  Rem================================================================  Rem= 参数说明:  Rem= pid当前ID,prame:栏目前辍(如一般web_news表,字段时一般为wn_**,prame就代表wn)  Rem= ptable(表前辍.如一般表名是:站点名_表名(shenzhe_news) ptable:就代表shenzhe)  Rem= 说明:采用上面命名法,可使该过

上一篇,下一篇过程代码_ASP基础

Rem==上一篇== Rem================================================================ Rem= 参数说明: Rem= pid当前ID,prame:栏目前辍(如一般web_news表,字段时一般为wn_**,prame就代表wn) Rem= ptable(表前辍.如一般表名是:站点名_表名(shenzhe_news) ptable:就代表shenzhe) Rem= 说明:采用上面命名法,可使该过程达到通用 Rem=======

发表论文时,该不该引用arXiv上未出版的论文?

雷锋网 AI科技评论按:7月.8月接二连三的机器学习会议的论文评选中,论文的作者往往会被评委的一个问题激怒--评委在评选论文时,往往会说论文里引用的参考论文只是arXiv上的预印本.究其原因,目前arXiv上论文的水平参差不齐,很多论文都没有得出结果,或者引用别人错误的成果.在这种情况下,到底该不该引用arXiv上只是预印版的论文? Zachary C. Lipton在Approximately Correct上的一篇文章中发表了对在arXiv上引用论文的看法:该引用时当然要引用.他是加州大学圣

Java EE项目中的异常处理总结(一篇不得不看的文章)_java

为什么要在J2EE项目中谈异常处理呢?可能许多java初学者都想说:"异常处理不就是try-.catch-finally吗?这谁都会啊!".笔者在初学java时也是这样认为的.如何在一个多层的j2ee项目中定义相应的异常类?在项目中的每一层如何进行异常处理?异常何时被抛出?异常何时被记录?异常该怎么记录?何时需要把checked Exception转化成unchecked Exception ,何时需要把unChecked Exception转化成checked Exception?异

《下一代媒体:大变革》终结篇下一代领导

新媒体正在创造个人与社会间新的关系模式. 我们如何管理知识是发展的核心. FOCAS的最后一场会议探讨的是下一代媒体的全球性含义.这些新技术并未能使世界上许多极难处理的问题--贫困.暴力.专制--消失,但它们为解决这些问题,提供了新的可能性. 同时,每种技术都有其阴暗面,既能被用作善举,也可被用作罪恶.正如前国务卿Madeleine Albright所指出的,广播是一种强大的信息传播工具,但在卢旺达,它却被政府用来煽动仇恨,用作有计划地灭种和屠杀.前面引用的那篇<华盛顿邮报>的专栏中,Davi