Флажок enum тоже может работать, если вы сделаете его байтом enum:
[Flags] enum PesHeaders : byte { /* ... */ }
Это не обязательно верно, что "каждому объекту - при создании - дадут пространство в "КУЧЕ" для членских переменных". Каждый объект, который Вы создаете, займет некоторое ненулевое место где-нибудь для его членских переменных, но где составил, как Вы выделяете сам объект. Если объект имеет автоматический (стек) выделение, так также будут его элементы данных. Если объект будет выделен на свободном хранилище ("куча"), то так также будут ее элементы данных. В конце концов, каково выделение объекта кроме того из его элементов данных?
, Если выделенный стеку объект содержит указатель или другой тип, который тогда используется для выделения на "куче", то выделение произойдет на "куче" независимо от того, где сам объект был создан.
Для объектов с виртуальными функциями, каждому выделят vtable указатель, как будто это был явно объявленный элемент данных в классе.
Что касается функций членства, код для тех вероятен не отличающийся от свободно-функционального кода с точки зрения того, где он входит в исполняемое изображение. В конце концов, функция членства является в основном бесплатной функцией с неявным "этот" указатель как его первый аргумент.
Наследование не изменяет большую часть ничего.
я не уверен, что Вы имеете в виду о DLLs получение их собственного стека. DLL не является программой и не должен иметь никакой потребности в стеке (или "куча"), как возражает, что это выделяет, всегда выделяются в контексте программы, которая имеет ее собственный стек и "кучу". То, что был бы код (текст), и сегменты данных в DLL действительно имеет смысл, хотя я не опытен в реализации таких вещей в Windows (который я предполагаю, что Вы используете, учитывая свою терминологию).
Код существует в сегменте текста, и сколько кода сгенерировано на основе классов, довольно сложно. Скучный класс без виртуального наследования якобы имеет некоторый код для каждой функции членства (включая тех, которые неявно создаются при исключении, такие как конструкторы копии) только однажды в сегменте текста. Размер любого экземпляра класса, как Вы заявили, обычно размер суммы членских переменных.
Затем это становится несколько сложным. Несколько проблем...
При программировании, используйте sizeof оператор для определения размера объекта - никогда твердый код. Используйте грубую метрику "Суммы членского размера переменной + некоторый VTABLE (если это существует)" при оценке, как дорогие большие группы экземпляров будут и не волнуются чрезмерно о размере кода. Оптимизируйте позже, и если какая-либо из неочевидных проблем возвратится для значения чего-то, то я буду скорее удивлен.
Хотя некоторыми аспектами этого является зависимый поставщика компилятора. Весь скомпилированный код входит в раздел памяти в большинстве систем, названных 'текстом'. это является отдельным от обоих "куча" и разделы стека (четвертый раздел, 'данные', содержит большинство констант). Инстанцирование многих экземпляров класса подвергается пространству во время выполнения только для его переменных экземпляра, не для любой из его функций. При использовании виртуальных методов Вы получите дополнительный, но маленький, бит памяти, отложенной для виртуальной таблицы поиска (или эквивалентный для компиляторов, которые используют некоторое другое понятие), но его размер определяется количеством виртуальных раз методов количество виртуальных классов и независим от количества экземпляров во времени выполнения
, Это верно для статически и динамично связанный код. Фактический код все жизни в 'текстовом' регионе. Большинство операционных систем на самом деле может совместно использовать код dll через несколько приложений, поэтому если несколько приложений используют тот же dll's, только одна копия находится в памяти, и оба приложения могут использовать его. Очевидно, нет никаких дополнительных сбережений от общей памяти, если только одно приложение использует связанный код.
Вы не можете полностью точно сказать, сколько памяти класс или X объектов поднимут в RAM.
Однако для ответа на вопросы Вы корректны, что код существует только в одном месте, он никогда не "выделяется". Код поэтому на класс, и существует, создаете ли Вы объекты или нет. Размер кода определяется Вашим компилятором, и даже тогда компиляторам можно часто говорить оптимизировать размер кода, ведя к отличающимся результатам.
Виртуальные функции не отличаются, сохраняют (маленькие) добавленные издержки таблицы виртуальных методов, которая обычно на класс.
Относительно DLLs и других библиотек... правила не отличаются в зависимости от того, куда код прибыл из, таким образом, это не фактор в использовании памяти.
если скомпилировано как 32 бита. тогда sizeof (Панель) должен уступить 4. Нечто должно добавить 10 байтов (2 ints + 2 символа).
, Так как Нечто наследовано от Панели. Это - по крайней мере 4 + 10 байтов = 14 байтов.
GCC имеет атрибуты для упаковки структур, таким образом, нет никакого дополнения. В этом случае 100 записей подняли бы 1 400 байтов + крошечные издержки для выравнивания выделения + немного служебные из для управления памятью.
, Если никакой упакованный атрибут не определяется, это зависит от выравнивания компиляторов.
, Но это не рассматривает, сколько vtable память поднимает и размер скомпилированного кода.
Ваша оценка точна в основном случае, который Вы представили. Каждый объект также имеет vtable с указателями для каждой виртуальной функции, поэтому ожидайте ценность дополнительного указателя памяти для каждой виртуальной функции.
членские переменные (и виртуальные функции) от любых базовых классов являются также частью класса, поэтому включайте их.
Так же, как в c можно использовать sizeof (имя класса/тип данных) оператор для получения размера в байтах класса.
Да, правильно, код не дублирован, когда экземпляр объекта создается. Насколько виртуальные функции идут, надлежащий вызов функции определяется с помощью vtable, но это не влияет на создание объекта по сути.
DLLs (общие/динамичные библиотеки в целом) с отображенной памятью в пространство памяти процесса. Каждая модификация продолжена как Копия на записи (COW): единственный DLL загружается только однажды в память, и для каждой записи в изменяемое пространство копия того пространства создается (обычно размера страницы).
Очень трудно дать точный ответ на yoour вопрос, поскольку это - implementtaion иждивенец, но приближенные значения для 32-разрядной реализации могли бы быть:
int Bar::mProtectedVar; // 4 bytes
int Foo::mPublicVar; // 4 bytes
char Foo::mPublicVar2; // 1 byte
существуют проблемы allgnment здесь, и заключительное общее количество может составить 12 байтов. У Вас также будет vptr - говорят еще 4 байта. Таким образом, общий размер для данных составляет приблизительно 16 байтов за экземпляр. Невозможно сказать, сколько пространства код поднимет, но Вы корректны в размышлении, что существует только одна копия кода, совместно использованного всеми экземплярами.
, Когда Вы спрашиваете
, я предполагаю, что dlls получают свой собственный стек, "кучу", сегменты кода и сегменты данных.
ответ Th - то, что действительно нет большого различия между данными в DLL и данными в приложении - в основном они совместно используют все между ними, Это должно быть так, когда Вы думаете о приблизительно этом - если у них были различные стеки (например), как вызовы функции могли работать?
Информация, приведенная выше, очень мне помогает и дала мне некоторое представление о структуре памяти C ++. Но я хотел бы добавить, что независимо от того, сколько виртуальных функций в классе, всегда будет только 1 VPTR и 1 VTABLE на класс. В конце концов, VPTR указывает на VTABLE, поэтому нет необходимости в более чем одном VPTR в случае нескольких виртуальных функций.