函数探幽(3) --引用(3)

3.1.将引用用于结构
引用非常适合用于结构和类,而引入引用的目的也是为了用于这些类型。
有如下结构定义:

struct free_throws
{
    std;;string name;
    int made;
    int attempts;
    float percent;
};
//则可以这样编写函数原型:
void set_pc(free_throws & ft);
//如果不希望函数修改传入的机构,可使用const:
void display(const free_throws & ft);

下面通过一个示例来展示如何将引用用于结构,并展示它一些有趣的特点:

#include<iostream>
#include<string>
struct free_throws
{
    std::string name;
    int made;
    int attempts;
    float percent;
};

void display(const free_throws & ft);
void set_pc(free_throws & ft);
free_throws & accumulate(free_throws & target, const free_throws & source);

int main() {
    free_throws one = { "Ifelsa Branch", 13, 14 };
    free_throws two = { "Andor Knott", 10, 16 };
    free_throws three = { "Minnie Max", 7, 9 };
    free_throws four = { "Whily Looper", 5, 9 };
    free_throws five = { "Long Long", 6, 14 };
    free_throws team = { "Thorwgoods", 0, 0 };

    free_throws dup;

    set_pc(one);
    display(one);
    accumulate(team, one);
    display(team);

    //有趣的地方①
    display(accumulate(team, two));
    accumulate(accumulate(team, three), four);
    display(team);

    dup = accumulate(team, five);
    std::cout << "Displaying team:\n";
    display(team);
    set_pc(four);
    accumulate(dup, five) = four; //②
    std::cout << "Displaying dup after ill advised assignment:\n";
    display(dup);
    system("pause");
    return 0;
}

void display(const free_throws & ft) {
    using std::cout;
    cout << "Name: " << ft.name << '\t';
    cout << "Made: " << ft.made << '\t';
    cout << "Attempts: " << ft.attempts << '\t';
    cout << "Percent: " << ft.percent << '\n';
}
//函数set_pc的代码设置成员percent,按值传递不可行,所以按引用传递
void set_pc(free_throws & ft) {
    if (ft.attempts != 0)
    {
        ft.percent = 100.0f * float(ft.made) / float(ft.attempts);
    }
    else
    {
        ft.percent = 0;
    }
}
//函数accumulate()接收两个结构参数,并将第二个结构的成员attempts和made的数据添加到第一个结构的相应成员中。
free_throws & accumulate(free_throws & target, const free_throws & source) {
    target.attempts += source.attempts;
    target.made += source.made;
    set_pc(target);
    return target;
}

输出为:
输出为

  • ①:函数accumulate()修改了team,再返回指向它的引用,接下来,accumulate()的返回值作为参数传递给了display(),这意味着team传递给了display(),与下面代码等效:
accumulate(team, two);
display(team);

-

  • ②:这以独特的方式使用了accumulate();
    这条语句将值赋给函数调用,这是可行的相当于:
    accumulate(dup, five);
    duo = four;

这样的操作并不好。

-

  • 返回引用时需要注意的问题
    应避免返回函数终止时不再存在的内存单元引用,您应避免:
    const free_throws & clone2 (free_throws & ft)
    {
           free_throws newguy;
           newguy = ft;
           return newguy;
    }

newguy为临时变量的引用,函数运行完毕后它将不再存在,为避免这种问题,最好返回一个作为参数传递给函数的引用,作为参数的引用将指向调用函数使用的数据,因此返回的引用也将指向这些数据。
另一种方法是用new来分配新的存储空间:

const free_thorws & clone(free_throws & ft)
{
   free_throws * pt;
    *pt= = ft;
    return *pt;

第一条语句创建一个无名的free_throws结构,并让指针pt指向该结构,因此*pt就是该结构。上述代码似乎会返回该结构,但函数声明表面,该函数实际上将返回这个结构的引用。
调用clone()隐藏了对new的调用,这使得以后很容易忘记使用delete来释放内存。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值