工学1号馆

home

« | 返回首页 | »

C++引用不完全总结

By Wu Yudong on November 10, 2016

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++中引用的各种用法,以后接着补充。

未完待续……

如果文章对您有帮助,欢迎点击下方按钮打赏作者

Comments

No comments yet.
To verify that you are human, please fill in "七"(required)