Навигация
Главная
Поиск
Форум
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
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Модуль Forms 65535
ТЕХНОЛОГИИ ДОСТ... 63052
Имитационное мо... 58357
Реклама
Сейчас на сайте
Гостей: 5
На сайте нет зарегистрированных пользователей

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

База данных студентов на Delphi + Microsoft SQL Server
Моделирование процесса передачи данных по магистрали с основным и резерв...
Моделирование процесса обработки заданий пакетным режимом работы с квант...

Реклама



Подписывайся на YouTube канал о программировании, что бы не пропустить новые видео!

ПОДПИСЫВАЙСЯ на канал о программировании
Разберемся теперь с операцией присваивания.
Разберемся теперь с операцией присваивания. Так как в базовом классе операция 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 20 2013 02:12:51 · 0 Комментариев · 2333 Прочтений · Для печати

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


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



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

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

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

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

Пароль



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

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

Случайные загрузки
Библия для програ...
ScreenSaver [Исхо...
Паскаль и Дельфи....
Globus VCL Extent...
Самоучитель PHP 5...
Email
Прграммирование в...
Размещение элемен...
Правила программи...
Allsubmitter 4.7 ...
Animated Menus
Редактор текста (...
MP3 Архив v.2.0
C++ для начинающих
Scrrlcaptoin
Srinilist
Система баннеро-о...
Язык программиров...
Animation (Пример...
Файловый менеджер

Топ загрузок
Приложение Клие... 100480
Delphi 7 Enterp... 87879
Converter AMR<-... 20082
GPSS World Stud... 13526
Borland C++Buil... 12061
Borland Delphi ... 8671
Turbo Pascal fo... 7048
Visual Studio 2... 5005
Калькулятор [Ис... 4911
FreeSMS v1.3.1 3545
Случайные статьи
Содержание
Анализ результатов...
Использование прог...
Разделение памяти ...
Сам механизм RTTI ...
Что такое рекурсия
Заключение
Множественные инте...
Схема подключения ...
Поперечное сечение...
Разрешение адреса
функцию брандмауэр...
Упорядочивание пар...
Пример стека как с...
Обработка ошибок в...
Уникальные характе...
Представление дере...
Поиск значений
Удаление компонент...
Обнаружение С-адре...
Фаза подтверждения
Точная настройка д...
Фильтр
Обобщенное програм...
ОЦЕНКА НОВЫХ ВОЗМО...
Статистика



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


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