Очевидно, что программист одурачен константой b
Как кто-то однажды сказал, Вы продолжаете использовать это слово.Я не думаю, что это означает, что вы думаете, что это означает.
Const означает, что вы не можете изменить значение.Это не значит, что значение не может измениться.
Если программиста одурачивает тот факт, что какой-то другой код может изменить что-то, что они не могут, им нужно лучшее понимание псевдонимов.
Если программиста одурачивает тот факт, чтотокен «const» звучит немного как «константа», но означает «только для чтения», им нужно лучше понять семантику языка программирования, который они используют.
Так что если у вас есть метод получения, который возвращает constссылка, тогда это псевдоним для объекта, который вы не имеете права изменять.Это говорит ничего о том, является ли его значение неизменным.
В конечном счете, это сводится к отсутствию инкапсуляции, а не к применению закона Деметры.В общем, не изменяйте состояние других объектов.Отправьте им сообщение, чтобы попросить их выполнить операцию, которая может (в зависимости от их собственных деталей реализации) изменить их состояние.
Если вы сделаете B.m_value
закрытым, то вы не сможете написать Foo
у тебя есть.Вы можете либо сделать Foo
в:
void Foo(const B &b)
{
m_B.increment_by(b);
m_B.increment_by(b);
}
void B::increment_by (const B& b)
{
// assert ( this != &b ) if you like
m_value += b.m_value;
}
, либо, если хотите убедиться, что значение является постоянным, использовать временное значение
void Foo(B b)
{
m_B.increment_by(b);
m_B.increment_by(b);
}
Теперь приращение значения само по себе можетили может быть нецелесообразным, и его легко проверить в B :: increment_by.Вы также можете проверить, есть ли &m_b==&b
в A :: Foo, хотя, если у вас есть пара уровней объектов и объектов со ссылками на другие объекты, а не на значения (поэтому &a1.b.c == &a2.b.c
не означает, что &a1.b
== &a2.b
или &a1
== &a2
), тогда вы действительно должны просто знать, что любая операция потенциально является псевдонимом.
Псевдоним означает, что приращение на выражение в два раза отличается от приращения на значение выражения при первом его вычислении;реального пути обхода нет, и в большинстве систем затраты на копирование данных не стоят риска избежать псевдонима.
Передача аргументов, которые имеют наименьшую структуру, также работает хорошо.Если Foo () использует long, а не объект, от которого он должен получить long, то он не будет иметь псевдонимов, и вам не нужно будет писать другой Foo () для увеличения m_b на значение C.