Своеобразие русской архитектуры: Основной материал – дерево – быстрота постройки, но недолговечность и необходимость деления...
Папиллярные узоры пальцев рук - маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни...
Топ:
Характеристика АТП и сварочно-жестяницкого участка: Транспорт в настоящее время является одной из важнейших отраслей народного хозяйства...
Оценка эффективности инструментов коммуникационной политики: Внешние коммуникации - обмен информацией между организацией и её внешней средой...
Интересное:
Мероприятия для защиты от морозного пучения грунтов: Инженерная защита от морозного (криогенного) пучения грунтов необходима для легких малоэтажных зданий и других сооружений...
Отражение на счетах бухгалтерского учета процесса приобретения: Процесс заготовления представляет систему экономических событий, включающих приобретение организацией у поставщиков сырья...
Инженерная защита территорий, зданий и сооружений от опасных геологических процессов: Изучение оползневых явлений, оценка устойчивости склонов и проектирование противооползневых сооружений — актуальнейшие задачи, стоящие перед отечественными...
Дисциплины:
|
из
5.00
|
Заказать работу |
Содержание книги
Поиск на нашем сайте
|
|
|
|
Это потенциальная проблема в программе COUNTEN. Что будет, если мы захотим инициализировать значением объект класса CountDn? Сможем ли мы воспользоваться конструктором класса Counter с одним аргументом? Ответ будет отрицательным. Как мы видели в программе COUNTEN, компилятор будет использовать конструктор базового класса без аргументов. Мы должны написать новый конструктор для производного класса. Это показано в программе C0UNTEN2:
// counten2.cpp
// конструкторы в производных классах
#include <iostream>
using namespace std;
///////////////////////////////////////////////////////////
class Counter
{
protected: // заметьте, что тут не следует использовать private
unsigned int count; // счетчик
public:
Counter (): count () // конструктор без параметров
{ }
Counter (int с): count (с) // конструктор с одним параметром
{ }
unsigned int get_count() const
{ return count; }// получение значения
Counter operator++ () // оператор увеличения
{ return Counter (++count); }
};
//unsigned int Counter::get_count () const // получение значения
//{ return count; }
///////////////////////////////////////////////////////////
class CountDn: public Counter
{
public:
CountDn (): Counter () // конструктор без параметров
{ }
CountDn (int с): Counter (с)// конструктор с одним параметром
{ }
CountDn operator-- () // оператор уменьшения
{ return CountDn (--count); }
};
///////////////////////////////////////////////////////////
int main ()
{
CountDn c1; // переменные класса CountDn
CountDn c2(100);
cout << "\nc1 = " << c1.get_count (); // выводим значения на экран
cout << "\nc2 = " << c2.get_count ();
++c1; ++c1; ++c1; // увеличиваем c1
cout << "\nc1 = " << c1.get_count (); // показываем результат
--c2; --c2; // уменьшаем c2
cout << "c2 = " << c2.get_count (); // показываем результат
CountDn c3 = --c2; // создаем переменную сЗ на основе с2
cout << "\nсЗ = " << c3.get_count (); // показываем значение
cout << endl;
return 0;
}
Программа использует два новых конструктора класса CountDn. Это конструктор без аргументов:
CountDn (): Counter () { }
В этом конструкторе использована новая для нас возможность: имя функции, следующее за двоеточием. Она используется конструктором класса CountDn для вызова конструктора Counter() базового класса. Когда мы запишем в функции main()
CountDn cl:
компилятор создаст объект класса CountDn и вызовет конструктор класса CountDn для его инициализации. Конструктор в свою очередь вызовет конструктор класса Counter, который выполнит нужные действия. Конструктор CountDn() может выполнять и свои операции, кроме вызова другого конструктора, но в нашем случае это не требуется, поэтому пространство между скобками пусто.
Вызов конструктора в списке инициализации может быть лишним, но это имеет смысл. Мы хотим инициализировать поле, не важно, принадлежит оно базовому или производному классу, и перед выполнением любого оператора программы сначала будут выполнены операции конструктора.
В строке
CountDn с2 (100):
функции main() используется конструктор класса CountDn с одним аргументом. Этот конструктор вызывает соответствующий конструктор с одним аргументом из базового класса:
CountDn (int с): Counter (с) // параметр с передается в конструктор класса Counter { }
Такая конструкция означает, что аргумент с будет передан от конструктора CountDn() в Counter(), где будет использован для инициализации объекта.
В функции main() после инициализации объектов cl и с2 мы увеличиваем один из них и уменьшаем другой, а затем выводим результат. Конструктор с одним аргументом также используется в выражениях присваивания:
CountDn сЗ = --с2:
Перегрузка функций
Мы можем определять для производного класса методы, имеющие такие же имена, как и у методов базового класса. В этом случае имеет место перегрузка функций. Такая возможность может понадобиться, если для объектов базового и производного классов в вашей программе используются одинаковые вызовы.
Рассмотрим пример, основанный на программе STAKARAY из главы 7 «Массивы и строки». Эта программа моделировала стек, простое устройство хранения данных. Она позволяла помещать числа в стек, а затем извлекать их. При попытке отправить в стек слишком много чисел программа могла зависнуть по причине переполнения массива st [ ]. А при попытке извлечения количества чисел, большего, чем находится в стеке, результат мог быть бессмысленным, так как начинали считываться данные, расположенные в памяти за пределами массива.
Для исправления этих дефектов мы создадим новый класс Stack2, производный от Stack. Объекты класса Stack2 ведут себя так же, как объекты класса Stack, за исключением того, что мы будем предупреждать о попытке переполнить стек или извлечь число из пустого стека. Вот листинг программы STAKEN:
// staken.cpp
// перегрузка функций базового и производного классов
#include <iostream>
using namespace std;
#include <process.h> // для exit ()
///////////////////////////////////////////////////////////
class Stack {
protected: // Замечание: использовать private нельзя
enum { MAX = 3 }; // размер стека
int st[ MAX ]; // данные, хранящиеся в стеке
int top; // индекс последнего элемента в стеке
public:
Stack () // конструктор
{ top = -1; }
void push (int var) // помещение числа в стек
{ st[ ++top ] = var; }
int pop () // извлечение числа из стека
{ return st[ top-- ]; }
};
///////////////////////////////////////////////////////////
class Stack2: public Stack
{
public:
void push (int var) // помещение числа в стек
{
if (top >= MAX - 1) // если стек полон, то ошибка
{ cout << "\nОшибка: стек полон";
exit (1); }
Stack::push (var); // вызов функции push класса Stack
}
int pop () // извлечение числа из стека
{
if (top < 0) // если стек пуст, то ошибка
{ cout << "\nОшибка: стек пуст\п";
exit (1); }
return Stack::pop (); // вызов функции pop класса Stack
}
};
///////////////////////////////////////////////////////////
int main () {
Stack2 s1;
s1.push (11); // поместим в стек несколько чисел
s1.push (22);
s1.push (33);
cout << endl << s1.pop (); // заберем числа из стека
cout << endl << s1.pop ();
cout << endl << s1.pop ();
cout << endl << s1.pop (); // ой. а данных-то больше нет
cout << endl;
return 0;
}
В этой программе класс Stack тот же, что и в программе STAKARAY, за исключением того, что данные класса объявлены как protected.
|
|
|
Биохимия спиртового брожения: Основу технологии получения пива составляет спиртовое брожение, - при котором сахар превращается...
Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰)...
Папиллярные узоры пальцев рук - маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни...
Опора деревянной одностоечной и способы укрепление угловых опор: Опоры ВЛ - конструкции, предназначенные для поддерживания проводов на необходимой высоте над землей, водой...
© cyberpedia.su 2017-2026 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!