![]() |
|
Модераторы: bsa |
![]()
|
|
| EgoBrain |
|
||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 537 Регистрация: 23.3.2008 Где: Комната Репутация: нет Всего: 2 |
Из теории, если создается производный класс из двух, у которых общий родитель, то объект такого класса будет содержать в себе данные суперкласса два раза.
A / \ B C \ / D (A, A) ![]() Так утверждает А. Л. Фридман. Так же они утверждает что
У меня такой вопрос, почему объект выведенного класса из обычного суперкласса меньше памяти занимает чем объект класса выведнного из виртуального суперкласса?
|
||||||||||
|
|||||||||||
| k0rvin |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 442 Регистрация: 24.1.2010 Репутация: нет Всего: 5 |
-------------------- “Object-oriented design is the roman numerals of computing.” — Rob Pike All software sucks |
|||
|
||||
| EgoBrain |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 537 Регистрация: 23.3.2008 Где: Комната Репутация: нет Всего: 2 |
||||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 12 Всего: 72 |
Variant1:
Parent: 4 bytes for name Parent1: 4 bytes for Parent + 8 bytes for a,b = 12 bytes; Parent2: 4 bytes for Parent + 8 bytes for c,d = 12 bytes; Derived: 12 bytes for Parent1 + 12 bytes for Parent2 = 24 bytes; Variant2: Parent: 4 bytes for name Parent1: 4 bytes for Parent* + 8 bytes for a,b + 4 bytes for Parent = 16 bytes | 12 bytes without Parent; Parent2: 4 bytes for Parent* + 8 bytes for c,d + 4 bytes for Parent = 16 bytes | 12 bytes without Parent; Derived: 12 bytes for Parent1 + 12 bytes for Parent2 + 4 bytes for Parent = 28 bytes; |
|||
|
||||
| EgoBrain |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 537 Регистрация: 23.3.2008 Где: Комната Репутация: нет Всего: 2 |
math64, почему под name всего 4 байта, когда там 6 символов?
Получается схема не верна: ![]() Хотя Фридман и её приводит. То есть без виртуального наследования должно быть то что на картинке в первом посте, а с виртуальным как на этой картинке. А по логике и по вашему ответу получается наоборот: без виртуалзиции D получил в себя даныне B и C, каждый из которых имеет данные A, потому что справедливо:
|
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
потому что sizeof считает место занимаемое объектом, а не объем памяти используемый объектом. У тебя в объекте хранится только указатели. А данные, на которые он указывает, хранятся в статической области памяти. В твоих примерах без виртуального наследования создавались неполиморфные классы. А в случае виртуального наследования они были полиморфными. Попробуй для начала в обоих примерах добавить в Parent виртуальный деструктор, а затем посмотри на изменения. А для наглядности еще можешь заменить char *name на char name[10]. |
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 12 Всего: 72 |
Без виртуализации Parent1 и Parent2 содержат полный класс Parent.
При виртуальном наследовании они содержат скрытые указатели на Parent, а сам Parent располагается в конце класса. В Derived Parent имеется в одном экемпляре и не по тому смещению, что в базовых классах, поэтому Parent1 и Parent2 должны пользоваться встроенными в них указателями для доступа к Parent. Если добавить виртуальные методы (рекомендуется добавлять виртуальный деструктор), у каждого класса будет своя таблица вируальных методов, и даже если ты их не переопределишь в производном классе, компилятору придётся генерироватьметоды-переходники. Фридман в своих диаграммах эти скрытые указатели и таблицы виртульных методов не показывает,а в остальном всё правильно. |
|||
|
||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
||||
|
||||
| EgoBrain |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 537 Регистрация: 23.3.2008 Где: Комната Репутация: нет Всего: 2 |
Спасибо всем. Всетаки дело в служебных данных, а надежда была - вдруг что-то другое.
Попробую с деструктором поэксперементировать.. |
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 12 Всего: 72 |
А также с конструктором - и посмотрите сгенрированный ассемблерный код.
Накладные расходы очень велики - так что пользуйся только когда без виртуального наследования никак. |
|||
|
||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |