Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> размер класса 
:(
    Опции темы
rukudias
Дата 8.11.2007, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 201
Регистрация: 28.2.2007

Репутация: 0
Всего: 0



Привет Всем!
Есть класс в нем одно поле char
и один метод
почему размер класса 1 байт?

как тогда мы одращ к методу!

Есть класс в нем одно поле char
и один метод virtual
почему размер класса 1+4 байт?
это указ на таб виртуал функций?
Спасибо

PM MAIL   Вверх
Fazil6
Дата 8.11.2007, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата(rukudias @  8.11.2007,  13:40 Найти цитируемый пост)
почему размер класса 1+4 байт?это указ на таб виртуал функций?

да
PM MAIL   Вверх
Alek86
Дата 8.11.2007, 14:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



оффтоп
rukudias, ты, случаем, на брэйнфаке не пишешь? ;)


--------------------
user posted image    user posted image
PM MAIL   Вверх
bsa
Дата 8.11.2007, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(rukudias @ 8.11.2007,  13:40)
Привет Всем!
Есть класс в нем одно поле char
и один метод
почему размер класса 1 байт?

как тогда мы одращ к методу!

Очень просто. На этапе компиляции компилятор определяет какой метод должен быть вызван и подставляет его вызов. При этом методу неявно передается указатель на экземляр класса (для нестатических методов).
PM   Вверх
jonie
Дата 9.11.2007, 01:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



Цитата

Есть класс в нем одно поле char
и один метод virtual
почему размер класса 1+4 байт?
вообще гооворя довольно странно. обычно компиляторы всеже делают выравнивание по нормальной границе... а вообще все так должно быть в "пакованом" формате 8)


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Dims
Дата 9.11.2007, 03:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 1
Всего: 11



Потому что методы не содержатся внутри класса, а хранятся отдельно. Причём хранится ОДИН экземпляр метода для всех экземпляров класса.

В сущности, метод класса ничем не отличается от обычной глобальной функции, кроме того, что он получает ещё указатель на объект класса и кладёт его в переменную this.

То есть, например, вот такой код

Код


class A {
public:
    int field;

    void increment(int amout) {
      field += anount;
   }

}


полностью эквивалентен коду

Код


struct A {
    int field;


}

void increment(A* This, int amout) {
   This->field += anount;
}



Чтобы работать с первым методом, нужно записать имя переменной типа A, потом поставить точечку и затем записать в скобках остальные аргументы. А чтобы работать со вторым методом, нужно адрес переменной типа A передать в первом аргументе.

Какая разница, где указывается аргумент: перед точечкой или после скобочки? В структуре от этого всё равно ничего не прибавляется.

А вот виртуальная функция добавляет в структуру поле со своим адресом. Тело функции всё равно присутствует в памяти в единственном экземпляре, но зато появляется возможность косвенной адресации. То есть, если в наследнике будет переопределена эта виртуальная функция, то в поле адреса попадёт адрес другой функции. И код, написанный для базового класса, не заметив этого, вызовет не функцию базового класса, а функцию наследника.

Добавлено через 53 секунды
Тьфу, забыл точку с запятой после тела класса. Её ещё не отменили, кстати?
PM MAIL   Вверх
skyboy
Дата 9.11.2007, 03:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 1
Всего: 260



Цитата(Dims @  9.11.2007,  02:11 Найти цитируемый пост)
А вот виртуальная функция добавляет в структуру поле со своим адресом. 

разве адрес вызова виртуального метода располагается не в таблице виртуальных методов? А в объекте разве хранится не указатель на всю таблицу его виртуальных методов?  smile 
PM MAIL   Вверх
Ln78
Дата 9.11.2007, 09:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 274
Регистрация: 25.11.2006

Репутация: 13
Всего: 15



skyboy, насколько я знаю, в объекте хранятся указатели на все таблицы для всех базовых классов. Например
Код

class A1
{
   virtual int FunA1(void) {return 1;}
   virtual int FunA2(void) {return 2;}
   virtual int FunA3(void) {return 3;}
};

class B1
{
   virtual int FunB1(void) {return 11;}
   virtual int FunB2(void) {return 12;}
};

class AB2 : public A1, public B1
{
   virtual int FunAB1(void) {return 121;}
};

Размер AB2 будет 8 байт: один указатель на таблицу виртуальных методов класса А1, другой - класса B1. 

Это сообщение отредактировал(а) Ln78 - 9.11.2007, 09:16
PM MAIL   Вверх
Alexeis
Дата 9.11.2007, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



Цитата(Ln78 @  9.11.2007,  09:15 Найти цитируемый пост)
Размер AB2 будет 8 байт: один указатель на таблицу виртуальных методов класса А1, другой - класса B1. 

  Да нет же, таблица VMT у наследника объединяется таблицей VMT предка. У объекта только одна VMT.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
skyboy
Дата 9.11.2007, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 1
Всего: 260



Цитата(Ln78 @  9.11.2007,  08:15 Найти цитируемый пост)
в объекте хранятся указатели на все таблицы для всех базовых классов

а зачем такое может понадобиться?
PM MAIL   Вверх
Ln78
Дата 9.11.2007, 10:32 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 274
Регистрация: 25.11.2006

Репутация: 13
Всего: 15



Alexeis, по крайней мере, в VS это именно так: два указателя.

skyboy, я всех причин не знаю. Наверное, в том числе и для того, чтобы если класс наследует от двух других, имеющих одинаковую по сигнатуре функцию, у него была возможность выбрать любую из них.

P.S. Кстати, Alexeis, ты говоришь об объединении предка и потомка, а я - про разных предков.

Это сообщение отредактировал(а) Ln78 - 9.11.2007, 10:34
PM MAIL   Вверх
skyboy
Дата 9.11.2007, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 1
Всего: 260



Цитата(Ln78 @  9.11.2007,  09:32 Найти цитируемый пост)
а я - про разных предков

да. об этом я не подумал smile
PM MAIL   Вверх
MAKCim
Дата 9.11.2007, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(Alexeis @  9.11.2007,  10:22 Найти цитируемый пост)
Да нет же, таблица VMT у наследника объединяется таблицей VMT предка. У объекта только одна VMT.

не совсем
VMT одна, но объект содержит столько указателей (указывающих на данные внутри таблицы), сколько у его класса предков
Код

class A {
public:
    virtual void d() {}
    virtual void a() {}
};

class B {
public:
    virtual void b() {}
};

class C: public A, public B {
public:
    virtual void a() {}
    virtual void c() {}
};

int main() {
    A * a = new C();
   a -> a();
    return 0;
}

Код

_ZN1CC1Ev:    /* конструктор С */
.LFB16:
    pushq   %rbp
.LCFI14:
    movq    %rsp, %rbp
.LCFI15:    
    subq    $16, %rsp
.LCFI16:
    movq    %rdi, -8(%rbp)    /* сохранение указателя на объект */
    movq    -8(%rbp), %rdi
    call    _ZN1AC2Ev    /* вызов конструктора A*/
    movq    -8(%rbp), %rdi
    addq    $8, %rdi
    call    _ZN1BC2Ev    /* вызов конструктора B */
    movl    $_ZTV1C+16, %edx    /*  адрес элемента 2 в _ZTV1C */
    movq    -8(%rbp), %rax
    movq    %rdx, (%rax)
    movl    $_ZTV1C+56, %edx    /* адрес элемента 8 в _ZTV1C */
    movq    -8(%rbp), %rax
    movq    %rdx, 8(%rax)
    leave
    ret

...
main:    /* функция main() */
    movl    $16, %edi    /* выделение 16 байт под объект (два указателя по 8 байт) */
    call    _Znwm    /* собственно выделение */
    movq    %rax, %rbx
    movq    %rbx, %rdi    /* параметр конструктора С, т. е адрес объекта */
    call    _ZN1CC1Ev    /* вызов конструктора C */
    movq    %rbx, -16(%rbp)    /* сохранение указателя на объект */
    movq    -16(%rbp), %rax
    movq    (%rax), %rax    /* получение адреса указателя на функцию A :: d() в _ZTV1C */
    addq    $8, %rax    /* т. к вызываем переопределенный метод C :: a(), переходим к следующему элементу _ZTV1C, т. е получаем адрес указателя на функцию C :: a() в _ZTV1C */
    movq    (%rax), %rax    /* получаем адрес C :: a() из элемента _ZTV1C */
    movq    -16(%rbp), %rdi    /* параметр this */
    call    *%rax    /* вызов метода С :: a() */

...
/* VMT для C */
_ZTV1C:
/* +0 */    .quad   0
/* +8 */    .quad   _ZTI1C
/* +16 */    .quad   _ZN1A1dEv    /* метод A :: d() */
/* +24 */    .quad   _ZN1C1aEv    /* метод C :: a() */
/* +32 */    .quad   _ZN1C1cEv    /* метод C :: c() */
/* +40 */    .quad   -8
/* +48 */    .quad   _ZTI1C
/* +56 */    .quad   _ZN1B1bEv    /* метод B :: b() */
    .weak   _ZTI1C



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Alexeis
Дата 9.11.2007, 11:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



Ln78, а ну да, для множественного наследования нужно.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
rukudias
Дата 9.11.2007, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 201
Регистрация: 28.2.2007

Репутация: 0
Всего: 0



ВСЕМ респект и уважуха! smile 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0634 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.