返回什么好呢

题目描述

补全类 MyClass 的定义,使得其符合下文所规定的输入输出行为。

关于输入

多组数据。每组一行,含空格分隔的整数 m 和 n。

关于输出

先输出一行 42。

然后对每组输入数据,输出一行,为空格分隔的 m 和 n。

核心技巧

  • a.getObj() 就是 a 本身,因此返回绑定到 *this 的引用。
  • 根据 a 的只读性不同,a.getObj() 也有不同的只读性。因此,通过 a 的只读性区分两个重载,定义不同的返回值类型。

知识点整理

  • 如果返回值类型不是引用,那么 a.getObj() 是从 *this 复制初始化得到的临时值,对其修改不会影响到 a
  • 出现在成员函数签名结尾的 const 代表这个成员函数是否对 this 只读。只有只读的成员函数才能在只读对象(如 print 里的 a)上使用。
  • 出现在 const MyClass& 中的 const 代表这个引用本身是否只读。答案中的两个 const 具有不同的含义,且没有任何关系。
    int v;
    struct S {
        const int& f() {
            return v;
        }
        int& g() const {
            return v;
        }
    };
    // 成员函数 f 和 g 的区别是什么?
    
  • 只读成员函数中的 this 具有 const T* 类型,T 是所在的类。
  • 非只读的引用不能绑定到只读对象上;因为这样会允许通过非只读引用修改一个只读变量的值。

参考答案

#include <iostream>
#include <utility>
using std::cout, std::endl;

class MyClass {
public:
    int value;

    MyClass(int value = 42) : value{value} {}
    MyClass& getObj() {
        return *this;
    }
    const MyClass& getObj() const {
        return *this;
    }
};

// 一些黑魔法,避免你写出错误的代码
static_assert(std::is_const_v<std::
remove_reference_t<decltype(std::
declval<const MyClass&>().getObj())>>);

void print(const MyClass& a) {
    cout << a.getObj().value << endl;
}

int main() {
    int m, n;
    MyClass a;
    cout << a.value << endl;
    while (std::cin >> m >> n) {
        a.getObj() = m;
        cout << a.value << " ";
        a.getObj() = MyClass(n);
        print(a);
    }
}