Навигация
Главная
Поиск
Форум
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
ТЕХНОЛОГИИ ДОСТ... 64171
Имитационное мо... 58788
Реклама
Сейчас на сайте
Гостей: 8
На сайте нет зарегистрированных пользователей

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

База данных - словарь терминов на Delphi + Пояснительная записка
Моделирование работы участка термической обработки шестерен на GPSS + По...
Выбор наилучших альтернатив с использованием методов оптимизации на Delp...

Реклама



Подписывайся на 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 Комментариев · 2370 Прочтений · Для печати

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


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



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
Доступа к БД Fire...
Учебник для продв...
PHP5. Профессиона...
Самоучитель PHP 4
Игра змейка
Таймер и секундомер
Панель "Случайное...
C# в кратком изло...
Мод "register.php...
Comdrv
Анимированное поя...
CwstatusBar
Время загрузки ...
DateEdit
Меню проводника в...
API (Применение A...
Billenium Effects...
Распознавание иде...
Plasma

Топ загрузок
Приложение Клие... 100498
Delphi 7 Enterp... 88640
Converter AMR<-... 20084
GPSS World Stud... 14001
Borland C++Buil... 12268
Borland Delphi ... 8764
Turbo Pascal fo... 7062
Visual Studio 2... 5007
Калькулятор [Ис... 4986
FreeSMS v1.3.1 3547
Случайные статьи
Таблица помогает с...
Глава 12 Защита да...
Рисование и редакт...
Пример обработки т...
Клонирование в STR...
Групповые функции
— отправлять сообщ...
при создании масси...
Коммерческие и тех...
Настройки публикации
Files must be var ...
Invalid function n...
Шаринг
Перед каждой транс...
Определение версии...
Фаза создания экзе...
Создание баз LSDB ...
Разработчики
О поколениях интел...
Модификации лэптопов
Microsoft и NetWar...
учетными записями ...
Связывание фреймов
Простейшие алгорит...
Динамическая компо...
Статистика



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


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