2013-07-16 3 views
0

Я работаю во встроенном проекте C++, где планирую сделать так, чтобы память была статически распределена как можно больше. Итак, я пишу набор функций для переопределения new/delete для всех классов и для глобального new/delete.Получение sizeof (MyClass) в объявлении члена класса

Вот наивная реализация:

class MyClass 
{ 
    int x; 
    float y; 
    double z; 

    static MyClass m_preAllocatedObjects[100]; //Solution 1 
    static char m_preAllocatedMemory[100 * sizeof(MyClass)]; //Solution 2 
    static char* getPreAllocatedMemory() // Solution 3 
    { 
     static char localStaticMemory[100 * sizeof(MyClass)]; 
     return localStaticMemory; 
    } 

    static void* operator new(size_t s){ 
    void* p; /*fill p from the pre-allocated memory or object*/; 
    return p; 
    } 
}; 

Решение 1: Это работает для объекта только с конструктором по умолчанию.

Решение 2: Дает компиляционную ошибку use of undefined type 'MyClass'; и это то, о чем я прошу около.

Решение 3: Это решение отлично работает.

Возникает вопрос:

Почему я могу создать статические члены MyClass, в то время как я не могу получить SizeOf (MyClass)?

+0

Вы можете создать статический массив указателей на ваш объект и наделяют любой конструктор вы хотите. Статический вектор unique_ptr был бы лучшим, поскольку он будет автоматически удаляться. –

ответ

3

пока я не могу получить sizeof (MyClass)?

Причина заключается в том, что MyClass не будет полностью определена до закрытия } определения класса, из раздела 9 классов из C++ 11 стандарта (проект n3337):

А Класс -name вставляется в область, в которой он объявляется сразу после просмотра имени класса. Имя класса также вводится в объем самого класса; это известно как имя введенного класса. Для проверки доступа имя введенного класса рассматривается как имя публичного участника. A Спецификатор класса обычно называется определением класса. Класс считается определенным после закрытия Скобка его спецификатора класса была видна, хотя ее функции-члены, как правило, еще не определены. Необязательный атрибут-спецификатор-seq относится к классу; атрибуты в атрибуте-спецификаторе-seq равны , после чего рассматриваются атрибуты класса при его названии.

и sizeof могут быть применены только к полному типу, из раздела 5.3.3 SIZEOF:

Оператор SizeOf дает количество байтов в объекте представления операнда. Операндом является либо выражение, которое является неоцененным операндом (раздел 5), либо идентификатором типа в скобках. Оператор SizeOf не должен быть применен к выражению, которое имеет функцию или неполного типа, к типу перечисления , чей базовый тип не является фиксированным, прежде чем всеми его счетчики были признаны, в круглых скобках имени таких типов, или к значению l, которое обозначает бит-поле. ...

Чтобы исправить, определить размер массива вне определения класса:

class MyClass 
{ 
    static char m_preAllocatedMemory[]; 
}; 

char MyClass::m_preAllocatedMemory[100 * sizeof(MyClass)]; 
3

Чтобы «знать» размер MyClass компилятор должен будет знать весь класс. Когда вы вперед объявить static MyClass m_preAllocatedObjects[100]; вы на самом деле не является определяющим переменным - на самом деле получить переменный, вы должны сделать:

MyClass MyClasss::m_preAllocatedObjects[100]; 

где-то в файле .cpp. Здесь память для объектов «помещается» в виде куска в сегменте данных. Поэтому компилятор не должен знать фактический размер MyClass в точке, где вы объявляете переменную. Однако он должен знать размер для оценки 100 * sizeof(MyClass).

+0

Затем компилятор должен также «знать» весь тип перед созданием массива этого типа? Почему «статический MyClass m_preAllocatedObjects [100]» работает без проблем? – Subhajit

+0

Как я уже сказал, фактический статический массив не «создается» до тех пор, пока вы его не определите в файле .cpp (или в файле .h, если только у вас есть только ONCE во всей программе). –

1

Вы должны сделать это в два этапа:

  • объявления массива (не зная его размер) внутри класса.
  • определяющий его, после того как вы закончите объявление класса, чтобы вы знали размер.

Вот код:

class MyClass 
{ 
    int x; 
    ... 
    static char m_preAllocatedMemory[]; 
}; 


char MyClass::m_preAllocatedMemory[100 * sizeof(MyClass)]; 
Смежные вопросы