Почему я не могу объявить ссылку на изменяемый объект? ( "ссылка не может быть объявлена изменчивой" )
Скажем, мы имеем a 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.
Почему?
Ответы
Ответ 1
Нет причин, чтобы ссылочный элемент изменялся. Зачем? Поскольку функции-члены 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;
};
Ответ 2
Ссылки могут быть назначены только при конструировании объекта и не могут быть изменены после этого. Таким образом, их mutable
не имеет смысла, поэтому стандарт запрещает его.
Ответ 3
В соответствии со стандартом:
[7.1.1, пункт 8]:
"Спецификатор mutable может применяться только к именам данных класса
членов (9.2) и не может применяться к именам, объявленным const или static,
и не может применяться к ссылочным членам. "
Так что это просто незаконно.
Ответ 4
Это может убрать ваш ум, но ссылка никогда не изменена (нельзя ссылаться на другой объект), а ссылочное значение всегда изменено (если у вас нет ссылки на 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 означает, что к членам добавляется определитель констант верхнего уровня. Для справки это ничего не делает (= int & const a;
), для указателя он делает указатель, а не pointee const (= int* const p
, not const int* p;
).