crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

daorus
  опции профиля:
сообщение 4.11.2010, 14:22
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 20
Регистрация: 30.10.2010
Пользователь №: 2163

Спасибо сказали: 0 раз(а)




Репутация:   0  


Захотелось мне любопытному B) узнать, сколько байтов добавляет к классу операция наследования от QObject, но может я что-то не так делаю? Подскажите в чем ошибка-то?

// параметры моей тачки
qDebug() << sizeof(int); // == 4
//
//
class e { public: e(){} };
e ept;
qDebug() << sizeof(ept); // == 1
//
//
class ine { public: ine(){ int a = 5; } };
ine inept;
qDebug() << sizeof(inept); // == 1
//
// #1. что происходит с int a в inept, когда я создаю два экземпляра ine?
//     почему функции не учитываются в sizeof?
//     они что - подобно *.dll'кам, т.е. носят share-характер вне зависимости от кол-ва экземпляров?
//     или просто конструкторы не могут быть inline'овыми?
//
// #2. существует ли какой-то дешевый способ подсчитать
//     стековую стоимость объекта вместе с его функциями   
//     или из-за возможности рекурсивных вызовов
//     получается калейдоскоп, не поддающийся подсчёту?
//     может тогда как-то можно подсчитать стоимость одной функции?
//
//
class eg { public: eg(){ a = 5; }; int a; };
eg egpt;
qDebug() << sizeof(egpt); // == 4
//
// #3. почему egpt == 4, а не egpt == 5, если ept == 1
//
//
class eo : public QObject
{
    Q_OBJECT
public:
    eo() { }
};
eo eopt;
qDebug() << sizeof(eopt); // == 8
//
// #4. неужели сделать потомком QObject'a какой-то класс стоит всего 8 байт?
//     при его навороченной-то функциональности, когда он даже имена типов хранит?
//     чё-то не верится...
//     а как тогда измерить реальную цену наследования от QObject'a?
//
//

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
2 страниц V   1 2 >  
Начать новую тему
Ответов (1 - 15)
Алексей1153
  опции профиля:
сообщение 4.11.2010, 14:48
Сообщение #2


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


daorus, пустой класс имеет размер 1 байт. Это какие-то заморочки, необходимые компилятору (детали не знаю)
class A
{
};

//sizeof(A)==1;


когда класс не пустой (к примеру, произведён от QObject) , то его (класса) размер становится равен размеру QObject (а единичка "пустоты" уже не учитывается)
class A:QObject
{
};

//sizeof(A)==sizeof(QObject);



Если класс сам что-то ещё содержит, то это также учтётся в размере
class A:QObject
{
   char c;
};

//sizeof(A) должен быть ==sizeof(QObject)+sizeof(c);


должен быть - но не обязательно равен, так как происходит ещё выравнивание (на 4 байта, если явно не задано другое)
размер также будет одинаков для таких вариантов:
class B
{
   QObject  o;
   char c;
};

class A:QObject
{
   char c;
};

//sizeof(A)==sizeof(B);



Цитата(daorus @ 4.11.2010, 16:22) *
// #4. неужели сделать потомком QObject'a какой-то класс стоит всего 8 байт?
// при его навороченной-то функциональности, когда он даже имена типов хранит?

указатель, например, всего 4 байта занимает :)

в исходниках нашёл нестатический мембер QObject такой

QScopedPointer<QObjectData> d_ptr;


Сообщение отредактировал Алексей1153 - 4.11.2010, 14:47
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 4.11.2010, 14:52
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(Алексей1153 @ 4.11.2010, 14:48) *
указатель, например, всего 4 байта занимает :)

Ну это не всегда. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 4.11.2010, 15:06
Сообщение #4


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


BRE, ну так то да. Я для 32-битной системы сказал по привычке :)

в 64-битной - 8 байтов
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
daorus
  опции профиля:
сообщение 4.11.2010, 16:13
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 20
Регистрация: 30.10.2010
Пользователь №: 2163

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 4.11.2010, 16:48) *
указатель, например, всего 4 байта занимает

Т.е. вы намекаете, что QObject внутри себя содержит указатель и поэтому sizeof(наследникQObject) == 8, и стало быть узнать сколько реально весит наследование от QObject понять нельзя, потому что придется под капотом искать QObjectData, а потом замерять sizeof(*d_ptr) и а что содержится в QObjectData хрен знает, там могут быть ещё указатели, а значит ещё объёмы и поэтому установить цену наследования от QObject практически нереально. Ход мыслей верный?

кстати, что показал тест
qDebug() << sizeof(QObjectData); // == 28

уже как говорится вперед
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 4.11.2010, 16:24
Сообщение #6


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


daorus, дык, я ж размер не замерял - я пример привёл, что размер объекта реально может и всего 4 байта составлять.

Насчёт посчитать реальный объём - через ОС API это наверняка возможно (сам не делал, не подскажу). Только нужно задаться вопросом - зачем :)

Если возник вопрос о том, что затратно наследоваться от QObject, то, может, этого делать просто не нужно ?

Сообщение отредактировал Алексей1153 - 4.11.2010, 16:23
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
daorus
  опции профиля:
сообщение 4.11.2010, 16:27
Сообщение #7


Студент
*

Группа: Участник
Сообщений: 20
Регистрация: 30.10.2010
Пользователь №: 2163

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 4.11.2010, 18:23) *
Только нужно задаться вопросом - зачем

хочется знать стоимость привычки. Речь идет о QT-разработке. Хочу узнать, если я на автомате буду объекты наследовать от QObject, чтобы вместо обычного указателя юзать QPointer<>, то сколько мне будет стоить такая привычка. Если она будет стоить, 28 байт на объект, ещё жить можно, а если пол-кило на объект, тогда лучше такую привычку не заводить. Вот собственно и хотел узнать как измерить или может сразу кто цифру назовет, какой размер оверхеда при наследовании от QObject.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 4.11.2010, 16:35
Сообщение #8


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


daorus, ну не знаю, мне ещё ни разу не пришлось наследоваться от QObject . От его детей - приходилось, но там объектов немного, так что 28 байтов на рожу - это совершенно ни на что не влияет.

Сообщение отредактировал Алексей1153 - 4.11.2010, 16:35
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
daorus
  опции профиля:
сообщение 4.11.2010, 21:38
Сообщение #9


Студент
*

Группа: Участник
Сообщений: 20
Регистрация: 30.10.2010
Пользователь №: 2163

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 4.11.2010, 18:35) *
28 байтов на рожу

Согласен. Особенно если функции, которые я включаю в свой объект в счёт не включаются, тогда вообще халява.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 4.11.2010, 23:45
Сообщение #10


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


daorus, функции располагаются в сегменте кода - и в единственном экземпляре для класса. Конечно же они не добавляют размер кэкземпляру класса.
Исключение - если есть виртуальные функции, то каждая такая функция увеличивает размер экземпляра класса на величину sizeof(void*) (размер указателя)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
daorus
  опции профиля:
сообщение 5.11.2010, 11:55
Сообщение #11


Студент
*

Группа: Участник
Сообщений: 20
Регистрация: 30.10.2010
Пользователь №: 2163

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 5.11.2010, 1:45) *
функции располагаются в сегменте кода - и в единственном экземпляре для класса
Ну, Лёха, даже не знаю как вас благодарить. Просто счастье, что именно вы смогли найти возможность ответить на мои вопросы. Огромное вам спасибо!

:drinks:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 5.11.2010, 13:19
Сообщение #12


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(daorus @ 5.11.2010, 14:55) *
Ну, Лёха, даже не знаю как вас благодарить
странная комбинация в обращении
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 5.11.2010, 13:42
Сообщение #13


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


сам в шоке до сих пор
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Влад
  опции профиля:
сообщение 7.11.2010, 17:25
Сообщение #14


Участник
**

Группа: Участник
Сообщений: 146
Регистрация: 20.3.2009
Из: Санкт-Петербург
Пользователь №: 627

Спасибо сказали: 46 раз(а)




Репутация:   8  


Цитата(Алексей1153 @ 4.11.2010, 14:48) *
daorus, пустой класс имеет размер 1 байт. Это какие-то заморочки, необходимые компилятору (детали не знаю)

Это вытекает из простого требования: каждый объект в памяти должен иметь уникальный адрес. Рассмотри, например, такую конструкцию:
class A {};

A my_array[100];
Если бы sizeof(A) был бы строго равен нулю, каковы были бы &my_array[0], &my_array[1] и так далее до &my_array[99]? Стандарт языка ведь требует, чтобы элементы массива были упакованы плотно, без пустот между ними - на этом строится адресная арифметика. А общий размер массива (sizeof(my_array))? А каковы были бы адреса переменных, объявленных "до" и "после" массива?

Поэтому размер любого объекта (даже "пустого" класса) - не менее 1 байта (а более - делать можно, но весьма бессмысленно, ибо пустой расход памяти). Как только же класс A наследуется от QObject, или же наоборот - от него наследуется какой-то класс (пусть A1, и например, непустой), - конечный класс становится заведомо "непустым", и лишние байты компилятору уже не нужны. Это называется "оптимизацией пустой базы" или "оптимизацией пустого базового класса" - empty base optimization.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 7.11.2010, 18:00
Сообщение #15


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Влад, понятно :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 9.11.2010, 10:52
Сообщение #16


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


Цитата(daorus @ 4.11.2010, 14:22) *
#1. что происходит с int a в inept, когда я создаю два экземпляра ine?

тут вопрос неосвещенным остался.
по идее int a рождается в стеке и героически умирает тут же, и нет никакой разницы сколько обЪектов ine создается.
Хотя умный компилятор может и рождать ничего не будет, - оптимизирует вызов к примеру и не будет создавать лишнюю неиспользуемую переменную. Хотя там предупреждение должно быть что она неиспользуемая.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 28.5.2025, 23:48