Private-Bookers
C++. Сборник рецептов
вернуться

Когсуэлл Джефф

Шрифт:
Обсуждение

Добавление концевого

const
в объявление члена и в его определение заставляет компилятор более внимательно отнестись к тому, что делается с объектом внутри тела члена. Константным функциям-членам не разрешается выполнять неконстантные операции с данными-членами. Если такие операции присутствуют, компиляция завершится неудачно. Например, если бы в
RecordSet::getFieldVal
я обновил счетчик-член, эта функция не была бы откомпилирована (в предположении, что
getFieldCount_
является переменной-членом класса
RecordSet
).

bool RecordSet::getFieldVal(int i, std::string& s) const {

 ++getFieldCount_; // Ошибка: константная функция-член не может

// модифицировать переменную-член

// ...

}

Это может также помочь обнаружить более тонкие ошибки, подобно тому, что делает

const
в роли квалификатора переменной (см. рецепт 15.3). Рассмотрим следующую глупую ошибку.

bool RecordSet::getFieldVal(int i, std::string& s) const {

 fieldArray_[i] = s; // Ой, я не это имел в виду

 // ...

}

Снова компилятор преждевременно завершит работу и выдаст сообщение об ошибке, потому что вы пытаетесь изменить переменную-член, а это не разрешается делать в константных функциях-членах. Ну, при одном исключении.

В классе

RecordSet
(в таком, как (схематичный) класс в примере 15.4) вам, вероятно, потребовалось бы перемещаться туда-сюда по набору записей, используя понятие «текущей» записи. Простой способ заключается в применении переменной-члена целого типа, содержащей номер текущей записи; ваши функции-члены, предназначенные для перемещения текущей записи вперед-назад, должны увеличивать или уменьшать это значение.

void RecordSet::gotoNextPecord const {

 if (curIndex_ >= 0 && curIndex_ < numRecords_-1)

++curIndex_;

}

void RecordSet::gotoPrevRecord const {

 if (curIndex_ > 0)

– -curIndex_;

}

Очевидно, что это не сработает, если эти функции-члены являются константными. Обе обновляют данное-член. Однако без этого пользователи класса

RecordSet
не смогут перемещаться по объекту
const RecordSet
. Это исключение из правил работы с константными функциями-членами является вполне разумным, поэтому C++ имеет механизм его поддержки: ключевое слово
mutable
.

Для того чтобы

curIndex_
можно было обновлять в константной функции-члене, объявите ее с ключевым словом mutable в объявлении класса.

mutable int curIndex_;

Это позволит вам модифицировать

curIndex_
в любом месте. Однако этой возможностью следует пользоваться разумно, поскольку это действует на вашу функцию так, как будто она становится с этого момента неконстантной.

Применение ключевого слова

const
в примере 15.4 позволяет гарантировать невозможность изменения состояния объекта в функции-члене. В целом, такой подход дает хорошие результаты, потому что сообщает пользователям класса о режиме работы функции-члена и потому что сохраняет вам репутацию, заставляя компилятор проконтролировать отсутствие в функции-члене непредусмотренных действий.

15.5. Написание оператора, не являющегося функцией-членом

Проблема

Необходимо написать бинарный оператор, и вы не можете или не хотите сделать его функцией-членом класса.

Решение

Используйте ключевое слово

operator
, временную переменную и конструктор копирования для выполнения основной работы и возвратите временный объект. В примере 15.5 приводится простой оператор конкатенации строк для пользовательского класса
String
.

Пример 15.5. Конкатенация с использованием оператора не члена

#include <iostream>

#include <cstring>

class String { // Предположим, что объявление класса String содержит,

// по крайней мере, все, что указанно ниже

public:

 String;

 String(const char* p);

 String(const String& orig);

 ~String {delete buf_;}

 String& append(const String& s);

 size_t length const;

 const char* data const;

 String& operator=(const String& orig);

 // ...

};

String operator+(const String& lhs, const String& rhs) {

 String tmp(lhs); // Сконструировать временный объект с помощью

// конструктора копирования

  • Читать дальше
  • 1
  • ...
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270

Private-Bookers - русскоязычная библиотека для чтения онлайн. Здесь удобно открывать книги с телефона и ПК, возвращаться к сохраненной странице и держать любимые произведения под рукой. Материалы добавляются пользователями; если считаете, что ваши права нарушены, воспользуйтесь формой обратной связи.

Полезные ссылки

  • Моя полка