Подтвердить что ты не робот

С++ Const Использование Объяснение

const int* const Method3(const int* const&) const;

Может кто-нибудь объяснить использование каждого из const?

4b9b3361

Ответ 1

Прочтите следующее: https://isocpp.org/wiki/faq/const-correctness

Окончательный const означает, что функция Method3 не изменяет не изменяемые элементы своего класса.

const int* const означает постоянный указатель на константу int: то есть указатель, который нельзя изменить, на int, который не может быть изменен: единственная разница между этим и const int& заключается в том, что он может быть null

const int* const& означает ссылку на константный указатель на константу int. Обычно указатели не передаются по ссылке; const int* & имеет больше смысла, потому что это будет означать, что указатель может быть изменен во время вызова метода, и это единственная причина, по которой я могу видеть указатель по ссылке, const int* const& для всех целей и задач такой же, как const int* const за исключением того, что он, вероятно, менее эффективен, поскольку указатели представляют собой простые старые данные (POD), и они должны, как правило, передаваться по значению.

Ответ 2

Это легче понять, если переписать это как полностью эквивалентный

// v───v───v───v───v───v───v───v───v───v───v───v─┬┐
//                                               ││
//  v──#1    v─#2             v──#3    v─#4      #5
   int const * const Method3(int const * const&) const;

затем прочитайте это справа налево.

# 5 говорит, что все объявление функции слева является const, что подразумевает, что это обязательно функция-член, а не свободная функция.

№ 4 говорит, что указатель слева является const (не может быть изменен, чтобы указывать на другой адрес).

# 3 говорит, что int слева является const (не может быть изменен, чтобы иметь другое значение).

№ 2 говорит, что указатель слева является const.

# 1 говорит, что int слева является const.

Собираем все вместе, вы можете прочитать это как const функции члена с именем Method3, который принимает ссылку на const указатель на int const (или const int, если вы предпочитаете) и возвращает const указатель на int const (const int).

(Примечание № 2 совершенно излишне.)

Ответ 3

Прежде всего const T эквивалентно T const.

const int* const поэтому эквивалентен int const * const.

При чтении выражений с большим количеством маркеров const и указателей в них всегда старайтесь читать их справа налево (после применения приведенного выше преобразования). Поэтому в этом случае возвращаемое значение является константным указателем на const int. Создание самого указателя const здесь не имеет смысла, поскольку возвращаемое значение не является значением l, которое может быть изменено. Однако создание указателя const гарантирует, что вызывающий абонент не может изменить int (или массив int s), возвращенный Method3.

const int*const& становится int const*const&, поэтому это ссылка на константный указатель на const int. Передача указателя const по ссылкам также не имеет смысла - вы не можете изменить ссылочное значение, так как указатель const, а ссылки и указатели занимают одинаковое хранилище, поэтому также нет экономии пространства.

Последний const указывает, что метод не изменяет объект this. Указатель this внутри тела метода будет иметь (теоретическое) объявление T const * const this. Это означает, что объект const T* сможет вызвать T::Method3().

Ответ 4

Легкий способ запомнить правила const заключается в том, чтобы думать об этом следующим образом: const применяется к предмету слева, если только ничего не осталось.

Итак, в случае const int * const первый const не имеет ничего слева, поэтому он применяется к int, а второй имеет что-то слева от него, поэтому он применяется к указателю.

Это правило также сообщает вам, что произойдет в случае, если у вас const int const *. Поскольку оба константы применяются к int, это выражение является избыточным и поэтому недействительным.

Ответ 5

Мне нравится использовать "clock" или "spiral" method, где, начиная с имени идентификатора (в данном случае Method3), вы читать назад и вперед слева-направо-назад-в -лево и т.д., чтобы декодировать соглашения об именах. Таким образом, const int* const Method3(const int* const&) const - это метод класса, который не изменяет никаких членов класса (некоторого неименованного класса) и принимает постоянную ссылку на указатель, который указывает на константу int и возвращает константный указатель на константу int.

Надеюсь, что это поможет,

Джейсон

Ответ 6

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 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 */

Ответ 7

Чтение справа налево облегчает понимание модификаторов.

Метод const, который ссылается на константный указатель на const int, называемый Method3, который возвращает указатель const на const int.

  • Метод const не может изменять элементы (если они не будут mutable)
  • Указатель const не может быть изменено, чтобы указать на что-то еще
  • const int (или любой другой тип) не может быть изменен

Ответ 8

const # 1: указатель, возвращаемый методом3, ссылается на const int.

const # 2: Значение указателя, возвращаемое самой функцией, является константой. Это бесполезный const (хотя и грамматически корректный), потому что возвращаемое значение из функции не может быть l-значением.

const # 3: тип указателя, переданный по ссылке на функцию, указывает на const int.

const # 4: значение указателя, переданное по ссылке на функцию, является самим собой, указателем const. Объявление значения, которое передается функции как const, обычно будет бессмысленным, но это значение передается по ссылке, поэтому оно может иметь смысл.

const # 5: Функция (предположительно, функция-член) является константой, что означает, что ей не разрешено (а) назначать новые значения любым членам объекта, частью которых она является, или (б) const-член объекта или любого из его членов.

Ответ 9

Легкий способ запомнить константу в С++ - это когда вы видите код в форме, например:

XXX const;
const YYY;

XXX, YYY будет постоянным компонентом,
Форма XXX const:

function ( def var ) const;    ------#1
* const;                       ------#2
Форма

const YYY:

const int;                     ------#3
const double;

Обычно люди используют эти типы. Когда вы видите "const&" где-то, не чувствуйте смущения, const описывает что-то перед собой. поэтому ответ на эту проблему теперь очевиден.

const int* const Method3(const int* const&) const;
  |          |             |          |       |
  #3         #2            #3         #2      #1

Ответ 10

Я хочу только упомянуть, что const int* const& действительно является постоянной ссылкой на const int*. Например:

int i = 0;
int j = 1;
int* p = &i;
int* q = &j;
const int* const& cpref = p;
cpref = q; //Error: assignment of read-only reference 'cpref'

Это также случай для int* const&, что означает: "Постоянная ссылка на int*".
Но const int*& является непостоянной ссылкой на const int*.
Надеюсь это поможет.

Ответ 11

  • const в конце метода не будет изменен определитель, обозначающий состояние объекта.

  • const int*const& означает получение по ссылке указателя const в местоположении const. Он не может ни переключиться на другое место, ни изменить значение, на которое оно указывает.

  • const int*const - это возвращаемое значение, которое также является постоянным указателем на постоянное местоположение.

Ответ 12

Несколько примеров могут показаться хорошими, чтобы продемонстрировать это понятие, тем лучше imho.

class TestClass
{
private:
   int iValue;
   int* oValuePtr;
   int& oValueRef;

public:
   int TestClass::ByValMethod1(int Value)
   {
      // Value can be modified
      Value++;

      // iValue can be modified
      iValue = Value;
      iValue += 1;

      // Return value can be modified
      return ++iValue;
   }

   int TestClass::ByValMethod2(const int Value)
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // iValue can be modified
      iValue = Value;
      iValue += 1;

      // Return value can be modified
      return ++iValue;
   }

   const int TestClass::ByValMethod3(int Value)
   {
      // Value can be modified
      Value++;

      // iValue can be modified
      iValue = Value;
      iValue += 1;

      // Return value can be modified
      return ++iValue;
   }

   const int TestClass::ByValMethod4(const int Value)
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // iValue can be modified
      iValue = Value;
      iValue += 1;

      // Return value can be modified
      return ++iValue;
   }

   const int TestClass::ByValMethod5(const int Value) const
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // iValue *cannot* be modified
      // Access through a const object
      iValue = Value;
      iValue += 1;

      // Return value *cannot* be modified
      // Access through a const object
      return ++iValue;
   }

   int& TestClass::ByRefMethod1(int& Value)
   {
      // Value can be modified
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   int& TestClass::ByRefMethod2(const int& Value)
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   const int& TestClass::ByRefMethod3(int& Value)
   {
      // Value can be modified
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   const int& TestClass::ByRefMethod4(const int& Value)
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   const int& TestClass::ByRefMethod5(const int& Value) const
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   int* TestClass::PointerMethod1(int* Value)
   {
      // Value can be modified
      Value++;

      // oValuePtr can be assigned
      oValuePtr = Value;

      // oValuePtr can be modified
      oValuePtr += 1;

      // Return value can be modified
      return ++oValuePtr;
   }

   int* TestClass::PointerMethod2(const int* Value)
   {
      // Value can be modified
      Value++;

      // oValuePtr cannot be assigned
      // const int* to int*
      oValuePtr = Value;

      // oValuePtr can be modified
      oValuePtr += 1;

      // Return value can be modified
      return ++oValuePtr;
   }

   const int* TestClass::PointerMethod3(int* Value)
   {
      // Value can be modified
      Value++;

      // oValuePtr can be assigned
      oValuePtr = Value;

      // iValue can be modified
      oValuePtr += 1;

      // Return value can be modified
      return ++oValuePtr;
   }

   const int* TestClass::PointerMethod4(const int* Value)
   {
      // Value cannot be modified
      Value++;

      // oValuePtr *cannot* be assigned
      // const int* to int*
      oValuePtr = Value;

      // oValuePtr can be modified
      oValuePtr += 1;

      // Return value can be modified
      return ++oValuePtr;
   }

   const int* TestClass::PointerMethod5(const int* 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 modified
      return ++oValuePtr;
   }
};

Надеюсь, это поможет!