【问题标题】:C++ const correctness with reference members引用成员的 C++ const 正确性
【发布时间】:2018-01-20 22:13:51
【问题描述】:

我在一个类中有一个 fstream & 成员,我在该类的 const 函数中调用 seekg 函数,但代码可以编译。我查了一下,seekg 没有声明为const(也不应该是),这是怎么回事?

这是我的代码:

class Test {
    fstream &f;
public:
    Test(fstream &f_): f(f_) {}
    int fid() const {
        f.seekg(5);
        return 0;
    }
};

【问题讨论】:

  • 您能否详细说明为什么您希望它无法编译?
  • 无法更改引用以引用不同的对象。引用的对象不是const
  • @Peter 所以你是说因为引用本质上是一个常量,所以它在这里引用的对象不需要是(类似于如果它是一个指针)?顺便说一句,从语义上讲,我们现在看到一个类的成员 f 正在被 const 函数更改,这有什么意义?
  • const 适用于 Test 的实例,而不适用于它们引用的其他对象。
  • const 被添加到顶层,你不能有 const 引用。所以T& const -> T&.

标签: c++ class constants


【解决方案1】:

事实证明const 不适用于指针或引用的成员,如here 所述。

我见过的最好的解释是here,它指出在const 成员函数中,thisconst T *,其中T 是类。

在您的示例中,这意味着 fid() 上的所有 const 修饰符所做的是将函数内部的 thisTest * 更改为 const Test *。当您编写f. 时,它以this->f. 访问,它的类型为fstream & const。引用是 const 但它所引用的不是,因此调用修改它的函数不会导致任何问题。

【讨论】:

  • 它确实适用于所有成员(尽管所有引用都是不可变的),但它不是可传递的(const 的指针/引用不会感染指针/裁判)。
  • "transitive" - 这是一种非常简洁的表达方式。我认为部分混淆是引用几乎感觉不像是间接的,所以传递性需要应用并不明显。但他们确实如此。
【解决方案2】:

规则定义在[expr.ref]/4:

如果 E2 被声明为类型“对 T 的引用”,那么 E1.E2 是一个左值; E1.E2 的类型是 T. [...]

在实践中,您应该考虑对 T 的引用,将其视为具有自动取消引用的 T 的 const 指针。内部这是参考。在标准内部,所有适用于引用的规则(例如,参见 [basic.life])都是适用于 const 指针的规则:

class Test {
  fstream * const f;
public:
  Test(fstream &f_): f(&f_) {}
  int fid() const {
    f->seekg(5);
    return 0;
  }
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 2018-12-29
    • 2012-02-13
    相关资源
    最近更新 更多