Почему я не могу объявить ссылку на изменяемый объект?(«ссылка не может быть объявлена ​​изменяемой») - PullRequest
26 голосов
/ 12 декабря 2011

Допустим, у нас есть 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.

Почему?

Ответы [ 4 ]

37 голосов
/ 12 декабря 2011

Нет причин для изменения ссылочного элемента.Зачем?Поскольку функции-члены 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;
};
11 голосов
/ 12 декабря 2011

в соответствии со стандартом: [7.1.1 пункт 8]:

"Изменяемый спецификатор может применяться только к именам данных класса members (9.2) и не могут применяться к именам, объявленным как const или static, и не может применяться к референтным членам. "

Так что это просто незаконно.

10 голосов
/ 12 декабря 2011

Ссылки могут быть назначены только при создании объекта и не могут быть изменены после этого. Таким образом, делать их mutable не имеет смысла, поэтому стандарт запрещает это.

3 голосов
/ 12 декабря 2011

Это может поразить ваш разум, но ссылка никогда не будет изменяемой (нельзя сделать ссылку на другой объект), а указанное значение всегда будет изменяемым (если у вас нет ссылки на const):

#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;), для указателя он делает указатель, а не pointee const (= int* const p, не const int* p;).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...