为什么不能声明一个可变对象的引用?("引用不能声明为可变")

27

假设我们有一个如下的test.cpp:

class A;

class B
{
    private:
        A mutable& _a;
};

编译:

$> gcc test.cpp
test.cpp:6:20: error: reference ‘_a’ cannot be declared ‘mutable’ [-fpermissive]

我的gcc:

$> gcc --version
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
为什么?

你在找指针吗? - Joe McGrath
1
即使您可以这样做,也是无用的,因为C++不包含任何可以更改引用的语法。您甚至无法获取引用的内存地址。如果尝试,则会获得引用指向的对象的地址。 - bames53
抱歉,我问错了问题。这不是可变引用,而是指向可变对象的引用!(我改了标题) - Martin
4个回答

47

没有理由将引用成员声明为mutable。为什么?因为const成员函数可以更改被类成员引用的对象:

class B {
public:
    B(int var) : n(var) {};
    void Set(int val) const { n = val; }  //no error
    void SetMember(int val) const { m = val; }  //error assignment of member `B::m' in read-only structure
protected:
    int& n;
    int m;
};

13

根据标准[7.1.1段8]:

"可变(mutable)修饰符只能应用于类数据成员(9.2)的名称,不能应用于声明为const或static的名称,并且不能应用于引用成员。"

因此,它是不合法的。


12

在构建对象时只能分配引用,之后无法修改引用。因此将它们设置为mutable没有任何意义,这就是标准不允许的原因。


2
但是引用可以是const或非const的。所以mutable A&a应该没问题,对吧?(现在不在编译器附近。) - Matt Phillips
2
但在这种情况下,mutable应用于被引用的对象,而不是引用本身。 - Sebastian Mach

5
这可能会让你大吃一惊,但引用永远不可变(不能被指向另一个对象),而引用的值始终是可变的(除非你有一个常量引用):
#include <iostream>

struct A
{
  int& i;
  A(int& n): i(n) {}
  void inc() const 
  {
    ++i;
  }
};

int main()
{
  int n = 0;
  const A a(n);
  a.inc();
  std::cout << n << '\n';
}

const方法意味着顶层的const限定符被添加到成员中。对于引用类型,这没有任何影响(= int & const a;),但对于指针类型,它会使指针本身变为const,而非指向的对象(= int* const p,而不是 const int* p;)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接