| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > размер класса |
| Автор: rukudias 8.11.2007, 13:40 |
| Привет Всем! Есть класс в нем одно поле char и один метод почему размер класса 1 байт? как тогда мы одращ к методу! Есть класс в нем одно поле char и один метод virtual почему размер класса 1+4 байт? это указ на таб виртуал функций? Спасибо |
| Автор: Fazil6 8.11.2007, 13:52 |
да |
| Автор: Alek86 8.11.2007, 14:19 |
| оффтоп rukudias, ты, случаем, на брэйнфаке не пишешь? ;) |
| Автор: bsa 8.11.2007, 14:26 | ||
Очень просто. На этапе компиляции компилятор определяет какой метод должен быть вызван и подставляет его вызов. При этом методу неявно передается указатель на экземляр класса (для нестатических методов). |
| Автор: jonie 9.11.2007, 01:38 | ||
|
| Автор: Dims 9.11.2007, 03:11 | ||||
| Потому что методы не содержатся внутри класса, а хранятся отдельно. Причём хранится ОДИН экземпляр метода для всех экземпляров класса. В сущности, метод класса ничем не отличается от обычной глобальной функции, кроме того, что он получает ещё указатель на объект класса и кладёт его в переменную this. То есть, например, вот такой код
полностью эквивалентен коду
Чтобы работать с первым методом, нужно записать имя переменной типа A, потом поставить точечку и затем записать в скобках остальные аргументы. А чтобы работать со вторым методом, нужно адрес переменной типа A передать в первом аргументе. Какая разница, где указывается аргумент: перед точечкой или после скобочки? В структуре от этого всё равно ничего не прибавляется. А вот виртуальная функция добавляет в структуру поле со своим адресом. Тело функции всё равно присутствует в памяти в единственном экземпляре, но зато появляется возможность косвенной адресации. То есть, если в наследнике будет переопределена эта виртуальная функция, то в поле адреса попадёт адрес другой функции. И код, написанный для базового класса, не заметив этого, вызовет не функцию базового класса, а функцию наследника. Добавлено через 53 секунды Тьфу, забыл точку с запятой после тела класса. Её ещё не отменили, кстати? |
| Автор: Ln78 9.11.2007, 09:15 | ||
skyboy, насколько я знаю, в объекте хранятся указатели на все таблицы для всех базовых классов. Например
Размер AB2 будет 8 байт: один указатель на таблицу виртуальных методов класса А1, другой - класса B1. |
| Автор: Alexeis 9.11.2007, 10:22 | ||
Да нет же, таблица VMT у наследника объединяется таблицей VMT предка. У объекта только одна VMT. |
| Автор: skyboy 9.11.2007, 10:25 | ||
а зачем такое может понадобиться? |
| Автор: Ln78 9.11.2007, 10:32 |
| Alexeis, по крайней мере, в VS это именно так: два указателя. skyboy, я всех причин не знаю. Наверное, в том числе и для того, чтобы если класс наследует от двух других, имеющих одинаковую по сигнатуре функцию, у него была возможность выбрать любую из них. P.S. Кстати, Alexeis, ты говоришь об объединении предка и потомка, а я - про разных предков. |
| Автор: skyboy 9.11.2007, 10:59 |
да. об этом я не подумал |
| Автор: MAKCim 9.11.2007, 11:04 | ||||||
не совсем VMT одна, но объект содержит столько указателей (указывающих на данные внутри таблицы), сколько у его класса предков
|
| Автор: Alexeis 9.11.2007, 11:56 |
| Ln78, а ну да, для множественного наследования нужно. |
| Автор: rukudias 9.11.2007, 13:10 |
| ВСЕМ респект и уважуха! |
| Автор: dumb 9.11.2007, 13:38 |
| кроме MAKCimа - он, негодяй, мало того что постоянно AT&T'шным ассемблером "сыплет", так теперь еще и 64-битным начал... озверел! |
| Автор: bsa 9.11.2007, 14:17 | ||
Ну зачем же так. Я, например, тоже на этом ассемблере немного даже пишу... |
| Автор: Dims 9.11.2007, 14:42 | ||
Ну да, я просто так для простоты сократил. |
| Автор: MAKCim 9.11.2007, 15:22 | ||
нет, кстати, обычно для примеров я использую Intel-синтаксис + 32-ух битный формат команд в этом примере букав много, влом было переводить так что уж извините |