const и нет методов const в c ++? - PullRequest
       1

const и нет методов const в c ++?

5 голосов
/ 15 октября 2010

У меня есть программа, и во многих ее классах есть некоторые операторы и методы с ключевым словом const, например:

operator const char* () const;
operator char* ();
void Save(const char *name) const;
void Load(const char *name);

Во-первых: что означает const в конце объявления метода? Это то же самое, что поставить его в начале?

Второе: зачем нужна константная версия и не константная версия operator ()?

Заранее спасибо.

Ответы [ 8 ]

8 голосов
/ 15 октября 2010

Во-первых: что означает const в конце объявления метода? Это то же самое, что поставить его в начале?

Нет.const в конце означает, что метод может быть вызван для объектов, которые объявлены const.const в начале означает, что возвращаемое значение равно const.

Второе: зачем нужна константная версия и не нужна константная версия оператора ()?*

Неконстантная версия возвращает char*, который не является константным.Изменяя этот char*, вы могли бы затем фактически изменить объект (предполагая, что char* является членом объекта).

Поскольку это не разрешено для const объектов, существует перегрузка operator() для константных объектов, так что возвращается const char*, поэтому объект не может быть изменен через него.

2 голосов
/ 15 октября 2010

'const' в конце говорит компилятору, что этот метод не изменяет никакие переменные-члены - что безопасно вызывать этот метод в экземплярах const Таким образом, Save можно вызывать для экземпляра const, поскольку он не изменит этот экземпляр. Загрузка, с другой стороны, изменит экземпляр, поэтому его нельзя использовать в экземплярах const.

Константная версия operator () возвращает указатель const, гарантируя, что переданный обратно буфер не изменится. Предположительно это указатель на переменную экземпляра класса. Для неконстантных экземпляров другой оператор () возвращает неконстантный указатель. Это должен быть указатель на некоторую память, которая даже при записи в нее не изменит содержимое экземпляра.

Кроме того, иногда ищите ключевое слово 'mutable'. Понимание этого поможет вам понять эту идею правильности.

2 голосов
/ 15 октября 2010

Константность функции-члена.Это означает, что функция не может (*) изменять какие-либо переменные-члены.Это как поставить const перед всеми переменными-членами для этого вызова одной функции.Это хорошая гарантия для клиентов вашего класса, а также может помочь в оптимизации компилятора.

(*) - см. Также ключевое слово mutable.

1 голос
/ 15 октября 2010

Чтобы узнать, когда рекомендуется использовать модификатор const для членов класса, вы должны обратиться к « HIGH · INTEGRITY C ++ STANDARD MANUAL », чтобы узнать, когда рекомендуется:

Правило CPP High Integrity 3.1.8 : Объявить 'const' любую функцию-член класса, которая не изменяет внешне видимое состояние объекта. (QACPP 4211, 4214)

Обоснование : Хотя язык обеспечивает побитовую правильность констант, правильность констант следует рассматривать как логическую, а не побитовую. Функция-член должна быть объявлена ​​как const, если клиенту невозможно определить, изменился ли объект в результате вызова этой функции. Ключевое слово 'mutable' может использоваться для объявления данных-членов, которые могут быть изменены в константных функциях, его следует использовать только в том случае, если данные-члены не влияют на внешне видимое состояние объекта.

class C 
{ 
public: 
     const C& foo() { return * this; }    // should be declared const 
     const int& getData() { return m_i; } // should be declared const 
     int bar() const { return m_mi; }     // ok to declare const 
private: 
int m_i; 
mutable int m_mi; 
};

Ссылка Эффективная C ++ Item 21; Промышленная прочность C ++ 7.13;

1 голос
/ 15 октября 2010

Если вы ищете отличный ресурс по C ++ (включая советы по правильному использованию const), попробуйте "Effective C ++".

Полезный сайт по этому поводу: JRiddel.org

В C ++, когда вы объявляете метод const, помещая его ПОСЛЕ подписи метода, вы утверждаете, что «Этот метод не изменит никакие переменные экземпляра, отличные от mutable, в объекте, к которому он вызывается. "

const перед возвращаемым значением (например, const in: operator const char*...") заявляет, что он возвращает только переменный указатель на const char*.(Вы не можете изменять содержимое char*, но вы можете переназначить указатель.) Если вы напишите «const char* const ...», это будет постоянный указатель на постоянные символы.(const идет после звезды).

Несколько версий полезны, чтобы компилятор мог понять это:

const char* my_const_var = <object_name>();
char* my_var = <object_name>();

Крис

1 голос
/ 15 октября 2010

Одна заметка в дополнение к другим ответам: в вашем примере нет operator().

operator const char* () const;
operator char* ();

являются операторами преобразования, которые означают, что объекты класса могут быть неявно преобразованы в строки в стиле C, например,

void f(const MyClass& x, MyClass& y) {
  const char* x_str = x;
  char* y_str = y;
}

Объявление и использование operator(), что означает, что вы можете использовать объект типа класса, похожего на функцию, будет выглядеть так:

class MyClass {
public:
  const char* operator() (int x, int y) const;
  // ...
};

void g(const MyClass& obj) {
  const char* result = obj(3, 4);
}
1 голос
/ 15 октября 2010

Установка const в конце объявления метода означает, что сам объект, или this, имеет тип const вместо возвращаемого типа.

C ++ допускает перегрузку методов на const по сложным причинам. Недостаточно места для подробного описания. Но вот пара коротких.

  • Иногда есть смысл или полная необходимость в том, чтобы метод вел себя иначе, когда он вызывается из типа const. Самый простой пример - когда вы хотите вернуть значение const из метода const и неконстантное значение из обычного метода.
  • Независимо от того, является ли this const, резко изменяется привязка внутреннего метода. До такой степени, что это, по сути, станет двумя различными методами тела. Следовательно, имеет смысл разделить его на 2 разных метода.
0 голосов
/ 15 октября 2010
  1. Const в начале относится к возвращаемому значению. Const в конце относится к самому методу. Когда вы объявляете метод как «const», вы говорите, что не собираетесь изменять какие-либо переменные-члены класса в методе. Компилятор даже сделает некоторые базовые проверки, чтобы убедиться, что метод не изменяет переменные-члены. Константа в возвращаемом значении не позволяет вызывающей стороне изменять возвращаемое значение. Это может быть полезно, когда вы возвращаете указатели или ссылки на данные, управляемые классом. Это часто делается, чтобы избежать возврата копий сложных данных, которые могут быть дорогостоящими во время выполнения.

  2. Причина, по которой у вас есть два разных оператора, заключается в том, что версия "const" возвращает указатель const на то, что, вероятно, является внутренними данными класса. Если экземпляр класса является константным, то, скорее всего, вы хотите, чтобы возвращаемые данные также были константными. «Неконстантная» версия просто предоставляет метод, который возвращает изменяемое возвращаемое значение, когда вызывающая сторона имеет неконстантный экземпляр класса.

...