Тот же объект, что и константный и неконстантный, что я должен считать правильным?
-
20-12-2019 - |
Вопрос
У меня есть функция формы
return_type function(const argument_type & a, argument_type & b);
Если тот же объект передается как a
и b
, могу ли я продолжить работу с функцией (тем самым потенциально изменяя ее) или остановиться?
У меня нет знаний о том, как распространяются предположения компилятора в этом случае.
Я предполагаю, что предположения о неконстантности для него передаются как неконстантные b
должно быть достаточно и разрешить изменения, но это предположение.
Большинство ответов касались того, чтобы быть способный модифицировать a
или b
, или вызвать неконстантные методы.Я знаю, что если я передам один и тот же объект обоим const
и non-const
Я могу это сделать.Мои сомнения больше связаны с тем, что я собираюсь выйти из программы, когда функция вернется, и может ли это нарушить некоторые предположения компилятора, например:
class A(){
int value;
}
void function1(const A & arg1);
void function2(A & arg1);
void function3(const A & arg1, A & arg2);
A a;
a.value=5;
function1(a);
if(a.value==5){/*...*/;} // the if can be optimized out to true, because [a] was const
a.value=5;
function2(a);
if(a.value==5){/*...*/;} //must be checked, [a] could have been modified
a.value=5;
function3(a, a);
if(a.value==5){/*...*/;} // ???
Самый похожий вопрос, который я нашел (но не совсем так)
Изменение self внутри метода const с помощью неконстантного указателя на себя
Решение
Проблема с
return_type function(const argument_type & a, argument_type & b);
и звонок function( o , o )
вероятно, это и есть та самая функция
изменяет объект с помощью формального аргумента
b
, в то время какв то же время ожидая формального аргумента
a
оставаться неизменным.
Таким образом, вы, вероятно, нарушите допущения функции, что приведет, например, кневерные результаты или сбой.
Есть одна функция, которая по замыслу часто имеет такой вид подписи, а именно оператор присваивания копии.Его постоянный формальный аргумент a
является аргументом, предоставляемым явно, а его изменяемый формальный аргумент (если его можно так назвать) является неявным *this
.Он может либо проверять наличие ссылки на себя (сглаживание аргументов), либо копировать и менять местами.
Подводя итог, можете ли вы безопасно вызвать функцию с тем же объектом в качестве аргумента a
и в качестве аргумента b
зависит от функции, но есть вероятность, что вы нарушите предположения функции о том, что она имеет в качестве неявного предварительного условия, что формальные аргументы ссылаются на разные объекты.
Другие советы
Вы решаете, можно ли назвать эту функцию с тем же аргументом дважды.
Во всяком случае, вы не должны пытаться определить, получаете ли вы один и тот же объект дважды, до тех пор, пока правильность вашего алгоритма не зависит от этого, или вы не дали никаких гарантий.
Они пропускаются точно так же, как пройти время, одинаковую ссылку / указатель на одно и то же.
Разница с const
происходит только при компиляционном времени.Компилятор убедитесь, что вы вызываете только методы const
и не пытаетесь изменять свойства этого объекта const
, в противном случае он бросает ошибку компиляции, потому что вы не должны изменять его.
Я предполагаю, что предположения о неконстантности для передачи как неконстантного b должны быть достаточными и позволять модификации, но это предположение.
Да, function
могу позвонить не-const
методы через b
но не через a
.
Интуитивно это означает, что function
может изменить объект, переданный через const
ссылка a
если тот же объект также передается через не-const
ссылка b
.
В общем, const
дает только гарантии относительно того, что вы можете или не можете сделать с const
переменная.Могут быть и другие переменные, которые относятся к const
переменной или объектам внутри нее, что может позволить const
переменная, которая будет изменена функцией, которая не выглядит так, как будто она изменяет const
переменная.
Возвращаясь к вашему случаю, речь идет о функциях и классах более высокого уровня, чем ваш function
для себя накладывают ограничения на то, что можно и что нельзя изменить с помощью const
параметры, функции-члены и т. д.