|
Программирование >> Дополнительные возможности наследования
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 itsVal(0) { > Counter;:Counter(int val); itsVal(val) { > Counter Counter::operator++() { ++itsVal; return Counter (itsVal); int main() { Counter i; cout The value of i is i.GetltsValO endl i. IncrementO; cout The value of i is i.GetltsValO endl ++i; cout The value of i is i.GetltsValO endl Counter a = ++i; cout The value of a: a. GetltsVaK); cout and i; i.GetltsValO endl; return 0; > The value of i is 0 The value of i is 1 The value of i is 2 The value of a: 3 and i: 3 В строке 11 определен новый конструктор, который принимает значе- ние типа int. Данный конструктор выполняется в строках с 27 по 29. Происходит инициализация переменной itsVal значением, переданным в параметре. Выполнение оператора инкремента в данной профамме упрощено. В строке 33 осуществляется приращение переменной itsVal. Затем в строке 34 создается временный объект класса Counter, которому присваивается значение переменной itsVal. Это значение затем возвращается как результат выполнения оператора инкремента. Подобное рещение выглядит более элегантно, но возникает вопрос, для чего вообще нужно создавать временные объекты. Напомним, что создание и удаление временного объекта в памяти компьютера фебует определенных временных зафат. Кроме того, если объект i уже существует и имеет правильное значение, почему бы просто не возвратить его? Реализуем эту идею с помошью указателя this. Испвльзованпв указатвля this На прошлом занятии уже рассматривалось использование указателя this. Этот указатель можно передавать в функцию-член оператора инкремента точно так же, как в любую другую функцию-член. Указатель this связан с объектом i и в случае разыменовывания возвращает объект, переменная которого itsVal уже содержит правильное значение. В листинге 10.11 показано возвращение указателя this, что снимает необходимость создания временных объектов. Апстинг 10.11. Возвращение указатвяя this 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 Листинг 10.11. Возвращение указателя this #include <iostream.h> class Counter { public: CounterO; CounterOi } int GetltsValOconst { return itsVal; void SetItsVal(int x) { itsVal = x; } void IncrementO { ++itsVal; } const Counter& operator++ (); private: int itsVal; Counter::Counter(): itsVal(O) { > ; const Counters Counter::operator++() { ++itsVal; return *this; int mainO { Counter i; cout The value of i is i.GetltsValO endl i.Increment(); cout The value of i is I.GetltsValO endl ++i; cout The value of i is i.GetltsValO endl 40 41 42 43 44 Counter a = ++i; cout The value of a: a.GetltsValO; cout and 1: I.GetltsValO endl; return 0; V 11 value of 1 is 0 The value of i is 1 The value of i is 2 The value of a: 3 and i; 3 Выполнение оператора приращения в строках с 26 по 30 заменено разы-меновыванием указателя this и возвращением текущего объекта. В результате объект класса Counter присваивается новому объекту а этого же класса. Как уже отмечалось выще, если объект класса Counter требует вьщеления намети, необходимо заместить конструктор-копировщик. Но в данном случае конструктор-копировщик, заданный по умолчанию, отлично справляется со своими задачами. Обратите внимание, что возвращаемое значение представляет собой ссылку класса Counter, благодаря чему отпадает необходимость в создании каких-либо дополнительных временных объектов. Ссылка задана как const, поскольку не должна менеться при использовании в функции. Пврвгрузка постфиксных оовраторов До сих пор рассматривалась перегрузка оператора преинкремента. Что если перегрузить оператор постинкремента? Тут перед компилятором встает проблема: как различить между собой операторы постинкремента и преинкремента. Существует договоренность, что при определении функции оператора постинкремента устанавливается целочисленный параметр. Значение параметра не имеет смысла. Он используется только как флаг, который сообщает, что перед нами оператор постинкремента. Разлпчня мвжду прсннкрвмвнтом и ностннкрвмвнтом Прежде чем приступить к перефузке оператора постинкремента, следует четко попеть, чем он отличается от оператора преинкремента. Подробно эта тема рассмафи-валась на занятии 4 (см. листинг 4.3). Вспомните, преинкремент означает прирастить, затем возвратить значение, а постинкремент - возвратить значение, а потом прирастить. Точно так же и в нащем примере оператор преинкремента приращивает значение, после чего возвращает объект, а оператор постинкремента возвращает объект с исходным значением. Чтобы проследить этот процесс, нужно создать временный объект, в котором будет сохранено исходное значение, затем выполнить приращение в исходном объекте и вновь вернуть его во временный объект. Давайте все это повторим еще раз. Посмотрите на следующее выражение: а = Х++; Если исходно переменная х равнялась 5, то в этом выражении переменной а будет присвоено значение 5, зато переменная х станет равной 5. Если х не просто переменная, а объект, то его оператор постинкремента должен сохранить исходное значение 5
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |