Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰)...
Своеобразие русской архитектуры: Основной материал – дерево – быстрота постройки, но недолговечность и необходимость деления...
Топ:
Комплексной системы оценки состояния охраны труда на производственном объекте (КСОТ-П): Цели и задачи Комплексной системы оценки состояния охраны труда и определению факторов рисков по охране труда...
Характеристика АТП и сварочно-жестяницкого участка: Транспорт в настоящее время является одной из важнейших отраслей народного хозяйства...
Оценка эффективности инструментов коммуникационной политики: Внешние коммуникации - обмен информацией между организацией и её внешней средой...
Интересное:
Подходы к решению темы фильма: Существует три основных типа исторического фильма, имеющих между собой много общего...
Берегоукрепление оползневых склонов: На прибрежных склонах основной причиной развития оползневых процессов является подмыв водами рек естественных склонов...
Влияние предпринимательской среды на эффективное функционирование предприятия: Предпринимательская среда – это совокупность внешних и внутренних факторов, оказывающих влияние на функционирование фирмы...
Дисциплины:
2020-05-08 | 209 |
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.
|
|
Своеобразие русской архитектуры: Основной материал – дерево – быстрота постройки, но недолговечность и необходимость деления...
Опора деревянной одностоечной и способы укрепление угловых опор: Опоры ВЛ - конструкции, предназначенные для поддерживания проводов на необходимой высоте над землей, водой...
Папиллярные узоры пальцев рук - маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни...
Историки об Елизавете Петровне: Елизавета попала между двумя встречными культурными течениями, воспитывалась среди новых европейских веяний и преданий...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!