![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Gunslinger |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 842 Регистрация: 30.12.2006 Где: Астрахань Репутация: 1 Всего: 3 |
Таким образом компилятор реализует и различные ограничители, вроде private, protected, namespace, const -- всего лишь добавляет к имени переменной\метода соответствующие "пометки"? Это сообщение отредактировал(а) Gunslinger - 20.2.2010, 17:55 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Ага, определение характеристик сущности в любом нужно-произвольном месте основывается на "пометках", которые компилятор запоминает для каждой сущности в процессе парсинга кода. Единственное, что не все пометки отражаются на имени. Полное имя нужно линкеру для связки - и на тот момент уже нет ни типов, ни скоупов, есть только имя. Компилятору необходимо гораздо больше информации (например тип, размер, право доступа), поэтому все "пометки" он хранит в специальных внутренних структурах. Как именно он хранит, каждый компилятор решает сам. |
|||
|
||||
| Gunslinger |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 842 Регистрация: 30.12.2006 Где: Астрахань Репутация: 1 Всего: 3 |
static переменные\методы, например? Существуют ведь в одной копии -- линкер вроде запутаться не должен. По поводу Вашего предыдущего примера кода.
b.A::f() -- вроде вызывается для объекта b, но у метода адрес на данные объекта а. Получается, f() возьмет не переменную "c" наследника, родителя: а.с? |
|||
|
||||
| mes |
|
||||||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
про запутаться :
какую f вызвать из этих линкеру было бы не понятно, поэтому для него обоим функциям задается вид типа например такого :
где в нашем случае для разделителя выбрано число показывающее кол-во символов до следующего разделителя. второй вариант, экспортировать имя функции в стиле, тогда у функции будет "нормальное" имя, но такая функция лишиться возможности перегрузки и расположения не в глобальном пространстве имен. В общем это уже в сторону от темы, и для разбора для начала почитать что такое mangling имен, и с чем его едят.
по адресу b есть данные как наследника , так и родителя,
да, так как мы указали явно что надо использовать функцию A::f будет вызвана именно она, а соответсвенно использоваться будет дата_член A::c. |
||||||||||
|
|||||||||||
| Gunslinger |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 842 Регистрация: 30.12.2006 Где: Астрахань Репутация: 1 Всего: 3 |
В b есть копия переменной-родителя, однако ни метод b.f(), ни b.a::f() не могут к ней обратиться: либо к b.c, либо к a.c. Как же тогда обратиться к [A::]с в наследнике? Знаю только, как в ActionScript3 такое сделано, но там все просто: super.наследованная_переменная. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
а в паскaле есть служебное слово inherited, ну а в С++ никаких служебных слов для этого не надо, достаточно указать специализированное имя переменной.
Это сообщение отредактировал(а) mes - 21.2.2010, 11:05 |
|||
|
||||
| Gunslinger |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 842 Регистрация: 30.12.2006 Где: Астрахань Репутация: 1 Всего: 3 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
ну так в самом начале же разбирали, что объект включает в себя все дата-члены как своего класса, так и всех предков. то есть объект класса B имеет следующие дата-члены :
так как с именем i две переменных, то имя определенное в наследнике скрывает имя определенное в предке, поэтому если необходимо обратиться к последнему, то необходимо уточнение (специализация имени). Ну а если например Вы б обратились например к переменной x, то так как их нет в описании класса и его предков, то компилятор предположил бы что обращаетесь к "наружней" (не к члену) переменной и начал бы искать подходящую там. Пример из жизни. Допустим Вы студент, и в Вашем классе есть Коля. Когда Вы говорите о нем со своими однокурсниками, то всем понятно о ком речь. Но на параллельном курсе тоже есть Коля, и когда Вы хотите упомянуть его, то должны уточнить о ком именно идет речь. А вот например парень с именем Аквакате только один на весь институт, и ни у кого сомнения не возникнет о ком идет речь, даже не уточняя. В общем язык программирования это тоже язык, и если в ЯНУ все плоско и каждая конструкция имеет только одно соответствие, то ЯВУ позволяет себе "такую же" игру слов как и разговорные язык и смысл конструкции не очевиден без знания контекста. для Си обычно приводят пример : что есть i * j ?; |
|||
|
||||
| Gunslinger |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 842 Регистрация: 30.12.2006 Где: Астрахань Репутация: 1 Всего: 3 |
Так ведь включает "копию", а не оригинал. Оригинал как принадлежал родителю, так и принадлежит... Вначале темы думал, что при наследовании создаются и копии методов, которые "перенаправляются" на унаследованные дата-члены. Оказалось ошибался -- копии методов не создаются и не "перенаправляются", а продолжают указывать на дата-члены родителя. Но теперь куча других вопросов: 1. Как обратиться к унаследованным переменным? 2. Если в родителе реализовывался какой-нибудь механизм (методы выполняли и писали состояние в дата-члены), то, если в наследнике предварительно не выполнить эти механизмы, то можно поломать логику работы наследника.. Как тогда быть, методы родителя же "направлены" на дата-члены родителя? |
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Ну вот приехали.. разберем на примере из жизни : Млекопитающего, как базового класса и волка как наследника.
Мы имеем два описания, притом второе включает в себя первое по принципу наследования. Фактически это говорит, что все что справедливо для объекта второго описания действительно и все что описано в первом. Описание и есть класс, при том первое описание - абстрактный класс, так как по нему не понятно какой именно объект имеется ввиду, и обладает недостаточной информацией для "построения" объекта данного класса второе описание - конкретный класс, так как обладает достаточной информацией для "построения" объекта данного класса. А вот и сам обьект, изображен на картинке : ![]() Как видно этому объекту соответствуют оба описания. В программировании говорится, что поддерживает оба интерфейса, что другими словами означает, что поведение объекта справедливо для обоих описаний. Также очевидно, что описаний может быть намного больше. Теперь хотелось бы уточнить сказанное в Вашей цитате, копии чего из класса содержит объект ?! Это сообщение отредактировал(а) mes - 23.2.2010, 13:22 |
||||
|
|||||
| mes |
|
||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
вот Вам еще один пример
Добавлено через 4 минуты и 30 секунд теперь построчный перевод вышеприведенного примера, но все методы заменены на обычные функции.
Добавлено через 10 минут и 1 секунду теперь тот же пример при отсутствии в языке механизма наследования
за соответсвие передаваемых типов отвечает не компилятор, а программист. Это сообщение отредактировал(а) mes - 23.2.2010, 11:58 |
||||||
|
|||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
опять тот же пример, но с отсутствием в языке механизма стуктур
Добавлено @ 12:17 думаю примеров Вам хватит, и в них вроде бы отражены вплоть до низшего уровня все вопросы этой темы. Это сообщение отредактировал(а) mes - 23.2.2010, 13:19 |
|||
|
||||
| Gunslinger |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 842 Регистрация: 30.12.2006 Где: Астрахань Репутация: 1 Всего: 3 |
Большое спасибо за терпеливое разъяснение и за пример с отсутствием структур -- очень доходчивый. Теперь понятно. Метод родителя можно "перенаправить" на унаследованные дата-члены -- это возможно за счет того, что в наследник добавляются сначала дата-члены родителя, а потом уже наследника. При такой последовательности методы родителя "знают" смещение "своих" унаследованных дата-членов. А как быть с множественным наследованием? Если class C: A, B, дата-члены В будут располагаться после дата-членов А, и тогда методы В будут "смотреть" не туда -- смещение будет неверным. Компилятор создает какой-нибудь дополнительный механизм? Это сообщение отредактировал(а) Gunslinger - 28.2.2010, 09:47 |
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
ура !
Это сообщение отредактировал(а) mes - 28.2.2010, 14:22 |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
вот Вам тогда еще один демонстрационный пример без структур, с учетом механизма множественного наследования.
P.S. в примере специально использовано двойное унаследование класса A классом AB () (прямое и косвенное посредством класса B), что делает пример не соответствующим правилам С++ из за появления неопределенностей преобразования (в нашем случае работает из за явного указания нужного преобразования), но имхо так лучше для понимания происходящего. Это сообщение отредактировал(а) mes - 28.2.2010, 15:44 |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |