Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 18
На сайте нет зарегистрированных пользователей

Пользователей: 13,361
новичок: uehuat
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Моделирование работы ЭВМ на GPSS + Пояснительная записка
Создание последовательности окон и передвижение окон по экрану на Turbo ...
Моделирование работы обрабатывающего участка цеха в GPSS

Разберемся теперь с операцией присваивания.
Разберемся теперь с операцией присваивания. Так как в базовом классе операция operator= не определена, компилятор создает ее по умолчанию. Как мы уже знаем (см. п. п. 12.8/10 в [1]), такая операция для базового класса имеет прототип:
TCurrency& operator=(const TCurrency &);



Для класса-наследника создается аналогичная функция:
Roubles& operator=(const Roubles &);



Наличие этих функций позволяет нам выполнять следующие присваивания:
TCurrency cl(10)( с2(11); // переменные базового класса
Roubles rl(20), г2(21); // переменные производного класса
cl = с2; // операция базового класса
rl = г2; // операция производного класса
cl = г2; // базовый = производный; операция базового класса



В последнем случае работает принцип подстановки: справа от присваивания задан объект производного класса, который подставляется на место объекта базового класса в операции присваивания.
Однако мы не можем выполнить присваивание
rl = cl; // производный = базовый



Неявное преобразование типа не работает, никакие явные преобразования не помогают. Такое присваивание не проходит и для указателей (ссылок), например:
TCurrency cl(10): // переменная базового класса
Roubles *рг: // указатель производного класса
pr = &cl; // ошибка трансляции



Компилятор сообщает, что он не может преобразовать адрес объекта базового класса в адрес производного. Чтобы это присваивание работало, требуется определить операцию присваивания с прототипом
Roubles& operator=(const TCurrency &);



Стандарт не запрещает писать такие операции присваивания. Более того, в любом классе можно неоднократно перегрузить операцию присваивания, в одной из которых, например, ни аргумент, ни результат не являются определяемым классом (см. п. п. 12.8/9 в [1]). Единственным ограничением является видимость определения нужных классов в точке определения операции присваивания.
В данном случае мы фактически должны написать функцию, аналогичную функции преобразования типа из базового типа в производный. Такое приведение в [11] названо понижающим.
ВНИМАНИЕ
В С++ понижающее приведение можно выполнить с помощью оператора преобразования dynamiccast (см. п. п. 10.3/1 в [1]), которое работает для полиморфных классов. Полиморфный класс — это класс с виртуальными функциями.

Именно из-за отсутствия такой операции не работал оператор f = d+d;
Рассмотрим, что должна делать эта функция и какие при этом возникают проблемы. В базовом классе такую функцию определить невозможно, так как базовый класс «понятия не имеет» о своих наследниках. Попытка ее создания немедленно приводит к ошибке трансляции класса TCurrency, так как Roubles не является определенным к этому моменту типом. Не спасает и предварительное объявление класса:
class Roubles:



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

«А давайте..!» — нет, открывать закрытые поля мы не будем. Не для того городился огород с инкапсуляцией, чтобы вот так просто его разрушить. Даже перевод полей в защищенные открывает «ящик Пандоры» — любой наследник получает к ним доступ. Вы только подумайте: достаточно унаследовать от TCurrency — и можно делать с суммами все, что заблагорассудится! Это — тот самый путь, который ведет в Ад.
Решение этой проблемы можно найти в стандарте (см. п. п. 12/1 в [1]):
Roubles& Roubles::operator=(const TCurrency &t)
{ this->TCurrency::operator=(t); // вызов родительской операции
return "this;




Собственно, самая главная «фишка» это вызов родительской операции в дочерней, причем в функциональной форме. Это работает, несмотря на то, что в родительском классе операция присваивания не была явно определена.
При наследовании денег не просматривается еще одна проблема, связанная с принципом подстановки. Чтобы понять, в чем дело, обратимся к классам точек и рассмотрим простой пример с двухмерными и трехмерными точками.
Point3D b(l,2,3);
Point2D а = b; // подстановка в конструкторе копирования - срезка
а = Ь; // подстановка в присваивании - срезка



Мобильные приложения необходимые для работы вне офиса вы можете найти тут http://softsprint.net/mobile/.
Работает принцип подстановки, однако нас поджидает неприятность: так как базовый класс ничего не знает о своих наследниках, то в переменную а копируется только двухмерная (Poi nt2D) часть трехмерной точки. Этот эффект называется срезкой [2], или расщеплением [11]; он частенько приводит к ошибкам. Например, при передаче параметра по значению, как мы знаем, работает конструктор копирования, поэтому в таких случаях тоже может произойти срезка. При передаче параметра по ссылке (или по указателю) ничего подобного не происходит. При передаче параметров в блок обработки исключения тоже может произойти срезка, поэтому параметр в секцию-ловушку лучше передавать по ссылке.
Опубликовал Kest November 19 2013 22:12:51 · 0 Комментариев · 3397 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
TrayComp
TDBF
Основы Delphi
DiZsubmit
Animation (Пример...
Rotolabel
Task Shedule
База каталогов ( ...
Дешифратор содерж...
3D Тетрис [Исходн...
Delphi 6. Учебный...
ADVstatusbar
Пример создания W...
CABfiles
Векторный редакто...
Упорядоченный дин...
AdBlaster v2.5 - ...
Отключение и вклю...
DFileDeleter
Нестандартные при...

Топ загрузок
Приложение Клие... 100772
Delphi 7 Enterp... 97809
Converter AMR<-... 20261
GPSS World Stud... 17014
Borland C++Buil... 14189
Borland Delphi ... 10267
Turbo Pascal fo... 7372
Калькулятор [Ис... 5972
Visual Studio 2... 5206
Microsoft SQL S... 3661
Случайные статьи
Организация подклю...
Процессоры XSLT
Изменение размеров...
Index TOP 20 (дохо...
4. Какую структуру...
Технология NetFlow
Office 365 уже сег...
Методы оптимизации...
Подсистема ввода-в...
Онлайн казино. Игр...
Листинг 13.22. Фун...
Слоты Вулкана
Определить суммы э...
Распространение по...
Оконная сигнализация
Сущность имитацион...
Установка регулято...
контроллеров домен...
Групповые адреса T...
Работа с MySQL в P...
Комбинирование пре...
Игровые автоматы. ...
Анализ приема. Раз...
2. Где применить О...
Идентификация объе...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?