Финал const означает, что функция Method3не изменяет неизменяемые члены своего класса.
const int* const означает постоянный указатель на константу int: то есть указатель, который не может быть изменен, на int, который не может быть изменен: единственная разница между this и const int& том, что он может бытьnull
const int* const&означает ссылку на постоянный указатель на константу типа int. Обычно указатели не передаются по ссылке; const int* &имеет больше смысла, потому что это будет означать, что указатель может быть изменен во время вызова метода, что было бы единственной причиной, по которой я мог бы передать указатель по ссылке, const int* const&во всех смыслах и целях одинаково, const int* constза исключением того, что он, вероятно, менее эффективен поскольку указатели представляют собой простые старые типы данных (POD), и они, как правило, должны передаваться по значению.
№5 говорит, что все объявление функции слева есть const, что означает, что это обязательно функция-член, а не бесплатная функция.
№4 говорит, что указатель слева есть const(не может быть изменен, чтобы указывать на другой адрес).
№3 говорит, что intслева есть const(не может быть изменено на другое значение).
№2 говорит, что указатель слева есть const.
№1 говорит, что intслева есть const.
Собрав все это вместе, вы можете прочитать это как функцию- constчлен с именем, Method3которая принимает ссылку на constуказатель на int const(или const int, если хотите) и возвращает constуказатель на int const(const int ).
const int* const поэтому эквивалентно int const * const .
При чтении выражений с большим количеством constтокенов и указателей всегда старайтесь читать их справа налево (после применения преобразования, описанного выше). Итак, в этом случае возвращаемое значение является указателем const на константуint . Создание самого указателя constздесь не имеет смысла, поскольку возвращаемое значение не является lvalue, которое можно изменить. Однако создание указателя constгарантирует, что вызывающий не может изменять int(или массив ints), возвращаемыйMethod3 .
const int*const&становится int const*const&, поэтому это ссылка на константный указатель на константуint . Передача константного указателя по ссылкам male тоже не имеет смысла - вы не можете изменить указанное значение, поскольку указатель есть, constа ссылки и указатели занимают одинаковую память, поэтому нет никакой экономии места.
Последнее constуказывает на то, что метод не изменяет thisобъект. thisУказатель внутри тела метода будет иметь (теоретически) заявление T const * const this. Это означает, что const T*объект сможет вызывать T::Method3().
Голосование за это (и аналогичный ответ ildjarn), отчасти для того, чтобы подчеркнуть, что все это имеет больше смысла, если вы не помещаете первые consts в начало фразы. Именно поэтому я считаю, что это плохая практика const, даже если язык позволяет это, и это наиболее распространенное использование.
TED
12
Легкий способ запомнить правила const- это думать об этом так: constприменимо к объекту слева от него, если слева от него ничего нет.
Итак, в случае const int * constс первой константой слева ничего нет, поэтому она применяется к, intа вторая имеет что-то слева, поэтому она применяется к указателю.
Это правило также говорит вам, что произойдет в том случае, если у вас есть const int const *. Поскольку обе константы применяются к intэтому выражению, это избыточно и поэтому недействительно.
const/* don't modify the int or array of ints' value(s) */int*const/* as a retval, ignored. useless declaration */Method3(const/* don't modify the int or array of ints' value(s) */int*const/* don't modify the pointer's value, the address to which `pointer` points to. e.g. you cannot say `++pointer` */&)const;/* this method does not modify the instance/object which implements the method */
Мне нравится использовать метод «часы» или «спираль», когда, начиная с имени идентификатора (в данном случае Method3), вы читаете туда и обратно слева направо, назад налево и т. Д., Чтобы декодировать соглашения об именах. Так const int* const Method3(const int* const&) constчто это метод класса, который не изменяет никаких членов класса (некоторого безымянного класса) и принимает постоянную ссылку на указатель, который указывает на константу, intи возвращает постоянный указатель на константу.int .
Самый простой способ запомнить константу в C ++ - это увидеть код в такой форме:
XXX const;const YYY;
XXX, YYY будет постоянным компонентом, XXX constформа:
function ( def var )const;------#1*const;------#2
const YYY форма:
constint;------#3constdouble;
Обычно люди используют эти типы. Когда вы что- "const&"то видите , не пугайтесь, const что-то описывает перед собой. так что ответ на эту проблему теперь очевиден.
Я только хочу упомянуть, что const int* const&это действительно постоянная ссылка на const int*. Например:
int i =0;int j =1;int* p =&i;int* q =&j;constint*const& cpref = p;
cpref = q;//Error: assignment of read-only reference 'cpref'
Это также относится к int* const&, Что означает: «Постоянная ссылка на int*».
Но const int*&это непостоянная ссылка на const int*.
Надеюсь это поможет.
const # 1: указатель, возвращаемый Method3, ссылается на const int.
const # 2: значение указателя, возвращаемое самой функцией, равно const. Это бесполезная константа (хотя грамматически правильная), потому что возвращаемое значение из функции не может быть l-значением.
const # 3: Тип указателя, переданный по ссылке в функцию, указывает на const int.
const # 4: значение указателя, переданное по ссылке в функцию, само является константным указателем. Объявление значения, которое передается функции как const, обычно бессмысленно, но это значение передается по ссылке, поэтому оно может иметь смысл.
const # 5: функция (предположительно, функция-член) является константой, что означает, что ей не разрешено (а) назначать новые значения любым членам объекта, частью которого она является, или (б) вызывать неконстантную функцию-член на объекте или на любом из его членов.
const в конце метода стоит квалификатор, означающий, что состояние объекта не будет изменено.
const int*const&означает получение по ссылке константного указателя на константное местоположение. Он не может ни указывать на другое местоположение, ни изменять значение, на которое указывает.
const int*const - это возвращаемое значение, которое также является постоянным указателем на постоянное местоположение.
Несколько примеров могут быть хороши для демонстрации этой концепции, чем больше, тем лучше imho.
classTestClass{private:int iValue;int* oValuePtr;int& oValueRef;public:intTestClass::ByValMethod1(intValue){// Value can be modifiedValue++;// iValue can be modified
iValue =Value;
iValue +=1;// Return value can be modifiedreturn++iValue;}intTestClass::ByValMethod2(constintValue){// Value *cannot* be modified// Variable is const variableValue++;// iValue can be modified
iValue =Value;
iValue +=1;// Return value can be modifiedreturn++iValue;}constintTestClass::ByValMethod3(intValue){// Value can be modifiedValue++;// iValue can be modified
iValue =Value;
iValue +=1;// Return value can be modifiedreturn++iValue;}constintTestClass::ByValMethod4(constintValue){// Value *cannot* be modified// Variable is const variableValue++;// iValue can be modified
iValue =Value;
iValue +=1;// Return value can be modifiedreturn++iValue;}constintTestClass::ByValMethod5(constintValue)const{// Value *cannot* be modified// Variable is const variableValue++;// iValue *cannot* be modified// Access through a const object
iValue =Value;
iValue +=1;// Return value *cannot* be modified// Access through a const objectreturn++iValue;}int&TestClass::ByRefMethod1(int&Value){// Value can be modifiedValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}int&TestClass::ByRefMethod2(constint&Value){// Value *cannot* be modified// Variable is const variableValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}constint&TestClass::ByRefMethod3(int&Value){// Value can be modifiedValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}constint&TestClass::ByRefMethod4(constint&Value){// Value *cannot* be modified// Variable is const variableValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}constint&TestClass::ByRefMethod5(constint&Value)const{// Value *cannot* be modified// Variable is const variableValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}int*TestClass::PointerMethod1(int*Value){// Value can be modifiedValue++;// oValuePtr can be assigned
oValuePtr =Value;// oValuePtr can be modified
oValuePtr +=1;// Return value can be modifiedreturn++oValuePtr;}int*TestClass::PointerMethod2(constint*Value){// Value can be modifiedValue++;// oValuePtr cannot be assigned// const int* to int*
oValuePtr =Value;// oValuePtr can be modified
oValuePtr +=1;// Return value can be modifiedreturn++oValuePtr;}constint*TestClass::PointerMethod3(int*Value){// Value can be modifiedValue++;// oValuePtr can be assigned
oValuePtr =Value;// iValue can be modified
oValuePtr +=1;// Return value can be modifiedreturn++oValuePtr;}constint*TestClass::PointerMethod4(constint*Value){// Value cannot be modifiedValue++;// oValuePtr *cannot* be assigned// const int* to int*
oValuePtr =Value;// oValuePtr can be modified
oValuePtr +=1;// Return value can be modifiedreturn++oValuePtr;}constint*TestClass::PointerMethod5(constint*Value)const{// Value can be modified++Value;// oValuePtr *cannot* be assigned// const int* to int* const// Access through a const object
oValuePtr =Value;// oValuePtr *cannot* be modified// Access through a const object
oValuePtr +=1;// Return value *cannot* be modifiedreturn++oValuePtr;}};
Ответы:
Прочтите это: https://isocpp.org/wiki/faq/const-correctness
Финал
const
означает, что функцияMethod3
не изменяет неизменяемые члены своего класса.const int* const
означает постоянный указатель на константу int: то есть указатель, который не может быть изменен, на int, который не может быть изменен: единственная разница между this иconst int&
том, что он может бытьnull
const int* const&
означает ссылку на постоянный указатель на константу типа int. Обычно указатели не передаются по ссылке;const int* &
имеет больше смысла, потому что это будет означать, что указатель может быть изменен во время вызова метода, что было бы единственной причиной, по которой я мог бы передать указатель по ссылке,const int* const&
во всех смыслах и целях одинаково,const int* const
за исключением того, что он, вероятно, менее эффективен поскольку указатели представляют собой простые старые типы данных (POD), и они, как правило, должны передаваться по значению.источник
Легче понять, если вы перепишете это как полностью эквивалентный
затем прочтите ее справа налево.
№5 говорит, что все объявление функции слева есть
const
, что означает, что это обязательно функция-член, а не бесплатная функция.№4 говорит, что указатель слева есть
const
(не может быть изменен, чтобы указывать на другой адрес).№3 говорит, что
int
слева естьconst
(не может быть изменено на другое значение).№2 говорит, что указатель слева есть
const
.№1 говорит, что
int
слева естьconst
.Собрав все это вместе, вы можете прочитать это как функцию-
const
член с именем,Method3
которая принимает ссылку наconst
указатель наint const
(илиconst int
, если хотите) и возвращаетconst
указатель наint const
(const int
).(Nb # 2 совершенно излишне .)
источник
Прежде всего
const T
эквивалентенT const
.const int* const
поэтому эквивалентноint const * const
.При чтении выражений с большим количеством
const
токенов и указателей всегда старайтесь читать их справа налево (после применения преобразования, описанного выше). Итак, в этом случае возвращаемое значение является указателем const на константуint
. Создание самого указателяconst
здесь не имеет смысла, поскольку возвращаемое значение не является lvalue, которое можно изменить. Однако создание указателяconst
гарантирует, что вызывающий не может изменятьint
(или массивint
s), возвращаемыйMethod3
.const int*const&
становитсяint const*const&
, поэтому это ссылка на константный указатель на константуint
. Передача константного указателя по ссылкам male тоже не имеет смысла - вы не можете изменить указанное значение, поскольку указатель есть,const
а ссылки и указатели занимают одинаковую память, поэтому нет никакой экономии места.Последнее
const
указывает на то, что метод не изменяетthis
объект.this
Указатель внутри тела метода будет иметь (теоретически) заявлениеT const * const this
. Это означает, чтоconst T*
объект сможет вызыватьT::Method3()
.источник
const
s в начало фразы. Именно поэтому я считаю, что это плохая практикаconst
, даже если язык позволяет это, и это наиболее распространенное использование.Легкий способ запомнить правила
const
- это думать об этом так:const
применимо к объекту слева от него, если слева от него ничего нет.Итак, в случае
const int * const
с первой константой слева ничего нет, поэтому она применяется к,int
а вторая имеет что-то слева, поэтому она применяется к указателю.Это правило также говорит вам, что произойдет в том случае, если у вас есть
const int const *
. Поскольку обе константы применяются кint
этому выражению, это избыточно и поэтому недействительно.источник
источник
Мне нравится использовать метод «часы» или «спираль», когда, начиная с имени идентификатора (в данном случае
Method3
), вы читаете туда и обратно слева направо, назад налево и т. Д., Чтобы декодировать соглашения об именах. Такconst int* const Method3(const int* const&) const
что это метод класса, который не изменяет никаких членов класса (некоторого безымянного класса) и принимает постоянную ссылку на указатель, который указывает на константу,int
и возвращает постоянный указатель на константу.int
.Надеюсь это поможет,
Джейсон
источник
Самый простой способ запомнить константу в C ++ - это увидеть код в такой форме:
XXX, YYY будет постоянным компонентом,
XXX const
форма:const YYY
форма:Обычно люди используют эти типы. Когда вы что-
"const&"
то видите , не пугайтесь, const что-то описывает перед собой. так что ответ на эту проблему теперь очевиден.источник
Я только хочу упомянуть, что
const int* const&
это действительно постоянная ссылка наconst int*
. Например:Это также относится к
int* const&
, Что означает: «Постоянная ссылка наint*
».Но
const int*&
это непостоянная ссылка наconst int*
.Надеюсь это поможет.
источник
Чтение справа налево упрощает понимание модификаторов.
Метод const, который принимает ссылку на указатель const на вызываемый const int,
Method3
который возвращает указатель const на const int.mutable
)источник
const # 1: указатель, возвращаемый Method3, ссылается на const int.
const # 2: значение указателя, возвращаемое самой функцией, равно const. Это бесполезная константа (хотя грамматически правильная), потому что возвращаемое значение из функции не может быть l-значением.
const # 3: Тип указателя, переданный по ссылке в функцию, указывает на const int.
const # 4: значение указателя, переданное по ссылке в функцию, само является константным указателем. Объявление значения, которое передается функции как const, обычно бессмысленно, но это значение передается по ссылке, поэтому оно может иметь смысл.
const # 5: функция (предположительно, функция-член) является константой, что означает, что ей не разрешено (а) назначать новые значения любым членам объекта, частью которого она является, или (б) вызывать неконстантную функцию-член на объекте или на любом из его членов.
источник
const
в конце метода стоит квалификатор, означающий, что состояние объекта не будет изменено.const int*const&
означает получение по ссылке константного указателя на константное местоположение. Он не может ни указывать на другое местоположение, ни изменять значение, на которое указывает.const int*const
- это возвращаемое значение, которое также является постоянным указателем на постоянное местоположение.источник
Несколько примеров могут быть хороши для демонстрации этой концепции, чем больше, тем лучше imho.
Надеюсь, это поможет!
источник