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

来源:互联网 发布:theme.custom.js 编辑:程序博客网 时间:2024/06/04 00:42

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来释放内存。

原创粉丝点击