Особенности сооружения опор в сложных условиях: Сооружение ВЛ в районах с суровыми климатическими и тяжелыми геологическими условиями...
Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...
Топ:
История развития методов оптимизации: теорема Куна-Таккера, метод Лагранжа, роль выпуклости в оптимизации...
Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов...
Характеристика АТП и сварочно-жестяницкого участка: Транспорт в настоящее время является одной из важнейших отраслей народного...
Интересное:
Что нужно делать при лейкемии: Прежде всего, необходимо выяснить, не страдаете ли вы каким-либо душевным недугом...
Распространение рака на другие отдаленные от желудка органы: Характерных симптомов рака желудка не существует. Выраженные симптомы появляются, когда опухоль...
Искусственное повышение поверхности территории: Варианты искусственного повышения поверхности территории необходимо выбирать на основе анализа следующих характеристик защищаемой территории...
Дисциплины:
|
из
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-2025 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!