C++ Primer学习笔记(6)—— 巧用引用形参

本文探讨了在C++中为何普通形参无法改变实参值的问题,解释了函数调用时实参是对象副本而非对象本身。通过引入引用形参的概念,展示了如何在函数中直接修改对象,从而解决参数交换的问题。此外,总结了使用引用形参的四种常见情况,包括改变参数对象、返回多个结果、高效传递大型对象以及处理私有构造函数的类类型。
摘要由CSDN通过智能技术生成

你是否遇到过这样的问题?写一个函数,实现两个数的交换。想当然的会写下面这样的函数:

void swap(int a,int b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
}
int main()
{
    int s1 = 10;
    int s2 = 20;
    cout << "交换前:s1 = "<<s1<<" , s2 = "<<s2<<endl;
    swap(s1,s2);
    cout << "交换后:s1 = "<<s1<<" , s2 = "<<s2<<endl;

    return 0;
}

结果是这样的:

交换前:s1 = 10 , s2 = 20
交换后:s1 = 10 , s2 = 20

并没有改变?!为什么呢?

其实,这里要区分函数的形参和实参。形参是在函数定义过程中定义的,在函数的形参列表中,必须标明参数的类型,是一个变量;实参是在函数调用过程中的,是一个表达式,用来给形参初始化的。

但是,要注意的是,传递的实参并不是对象本身,而是对象的副本,相当于是复制过来的。

所以问题的关键就在这里,上面传递s1, s2实参只是个副本,所以函数改变的只是副本,并没有改变s1,s2本身。
那么,怎么解决这个问题呢?

引用形参!!
把形参改成这样就可以了:

void swap(int &a,int &b)

这次的运行结果为:

交换前:s1 = 10 , s2 = 20
交换后:s1 = 20 , s2 = 10

原因是:引用实际是对象的别名,就像我们的小名儿,代表的是我们本身,而不是我们的克隆(副本)。所以,用引用作为形参,就直接代表对象本身,不是复制来的。函数改变的就是对象本身了。

总结一下:什么情况下使用引用形参呢?

牢记以下四种情况:

  • 需要通过函数调用改变参数对象的时候,如上面的例子;
  • 需要通过一次函数调用获得多个结果值;
  • 在想函数传递大型对象时,复制实参会降低效率,这时可以用引用形参;
  • 如果实参是类类型,且其构造函数为private类型,无法复制,这时只能使用引用形参了。

关于第二点有点难以理解,举例说明一下:

例如,定义一个fing_val函数,在一个整型vector对象的元素中搜索某个特定值,该值可能出现多次。请返回一个迭代器指向该值第一次出现的位置(1),以及出现的次数(2)。

所以需要返回两个值。而一般的函数只能通过return返回一个值。

这时可以巧用引用形参了:在函数形参中定义一个计数的引用形参 int &count ,函数搜索过程中计数,并改变count的值,那么函数执行完之后,count的值就代表了出现次数。而return的还是指向第一次出现位置的迭代器。

这样就满足了题目要求。

代码如下:

vector<int>::iterator find_val(vector<int>::iterator begin,
         vector<int>::iterator end,
         int value,
         vector<int>::size_type &count)
{
    vector<int>::iterator first = end;
    count = 0;
    for( ; begin != end ; ++begin)
    {
        if(*begin == value)
// 以下:如果first还是指向end说明是第一次value出现了,赶紧将first指向该位置。此后,first就不指向end了
            if(first == end)
                first = begin;
            ++count;
    }

    return first; //返回迭代器first,指向value第一次出现的位置
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值