C++:返回*this的成员函数


1. 函数返回引用类型

#include <iostream>
#include <string>
using namespace std;
class A
{
public:
    int a = 0; //数据成员

    // 返回引用
    A &f1() { return *this; }

    // 返回非引用
    A f2() { return *this; }

    // a+=1
    void combine() { a += 1; }
};

int main()
{
    A x, y;

    x.f1().combine();
    //等价于
    // A &temp1 = x.f1();
    // temp1.combine();

    y.f2().combine();
    //等价于
    // A temp2 = y.f2();
    // temp2.combine();

    cout << "x.a = " << x.a << endl;
    cout << "y.a = " << y.a << endl;

    return 0;
}

运行结果

函数名 this类型 *this类型 返回类型
f1 A *const A A&
f2 A *const A A

分析:

  1. f1的返回类型是A&,x.f1()返回的是对x的引用,对x.f1的操作会相应的修改x。
  2. f2的返回类型是A,y.f2()返回的是y的副本,对y.f2()的操作不会影响到y。

总结:

  1. 返回*this的成员函数可以合并在一条语句中。
  2. 对于返回*this的成员函数,若它的返回类型是引用,则返回值是对类对象的引用;若它的返回类型不是引用,则返回值是类对象的副本。

2. 常量成员函数

#include <iostream>
#include <string>
using namespace std;
class A
{
public:
    int a = 0; //数据成员

    // 非常量成员函数
    A &f1() { return *this; }

    // 常量成员函数
    const A &f2() const { return *this; }
};

int main()
{
    A x1; //非常量
    x1.f1();
    x1.f2();

    const A x2; // 常量
    x2.f1();    //错误
    x2.f2();

    return 0;
}

运行结果

函数名 this类型 *this类型 返回类型
f1 A *const A A&
f2 const A *const const A const A&

分析:

  1. x1是变量,f2是常量成员函数。x1调用f2时,this=&x1,this指向const A,x1是A,指向常量的对象可以指向相应的非常量对象,x1.f2()正确。
  2. x2是常量,f1不是常量成员函数。x2调用f1时,this=&x2,this指向A,x2是const A,类型不匹配,x2.f1()错误。

总结:

  1. 常量对象,以及对常量对象的引用和指针只能调用常量成员函数。
  2. 非常量对象可以调用常量成员函数和非常量成员函数。重载时编译器优先调用非常量成员函数。

3. 常量成员函数调用顺序

#include <iostream>
using namespace std;
class A
{
public:
    int a = 0; //数据成员

    A &add()
    {
        a += 1;
        return *this;
    }

    const A &show() const
    {
        cout << a << endl;
        return *this;
    }
};

int main()
{
    // 先a+1, 再打印a
    A a1;
    a1.add();  //this=&a1, this指向A,       a1是A
    a1.show(); //this=&a1, this指向const A, a1是A

    A a2;
    a2.add().show();// a2.add()的结果不是常量,可以调用常量成员函数

    // 先打印a, 再a+1
    A a3;
    a3.show(); //this=&a3, this指向const A, a3是A
    a3.add();  //this=&a3, this指向A,       a3是A

    A a4;
    a4.show().add(); // 错误,a4.show()的结果是常量。常量对象只能调用常量成员函数,add不是常量成员函数

    return 0;
}

报错提示

函数名 this类型 *this类型 返回类型
add A *const A A &
show const A *const const A const A &

分析:

  1. a1本身不是常量,它可以调用普通成员函数add和常量成员函数show。a1.add()返回一个绑定a1的引用,这个引用对a1.show()无影响。
    A a1;
    a1.add();  //this=&a1, this指向A,       a1是A
    a1.show(); //this=&a1, this指向const A, a1是A
    //等价于
    A &tem1 = a1.add();
    a1.show();
  1. a2本身不是常量,它可以调用普通成员函数add。a2.add()返回一个绑定a2的引用,该引用不是对常量的引用,它可以调用常量成员函数show。
    A a2;
    a2.add().show();
    //等价于
    A &temp2 = a2.add();
    temp2.show();
  1. a3本身不是常量,它可以调用常量成员函数show和普通成员函数add。a3.show()返回一个绑定a3的引用,这个引用对a3.add()无影响。
    A a3;
    a3.show(); //this=&a3, this指向const A, a3是A
    a3.add();  //this=&a3, this指向A,       a3是A
    //等价于
    const A &temp3 = a3.show();
    a3.add();
  1. a4本身不是常量,它可以调用常量成员函数show。a4.show()返回一个绑定a4的引用,该引用是对常量的引用,它只能调用常量成员函数,不能调用普通成员函数add。
    A a4;
    a4.show().add(); // 错误
    //等价于
    const A &temp4 = a4.show();
    temp4.add();

总结:

  1. 普通成员函数与常量成员函数合并在一条语句时注意其先后顺序,其合并和拆开后含义可能不同,如a1和a2是含义相同,a3和a4含义不同。
发布了77 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_34801642/article/details/104559575
今日推荐