0

我在嵌入式 C++ 项目中工作,我计划在其中尽可能多地静态分配内存。因此,我正在编写一组函数来覆盖所有类和全局 new/delete 的 new/delete。

这是一个幼稚的实现:

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)?

4

3 回答 3

3

要“知道”MyClass编译器的大小,需要知道整个类。当您向前声明 a 时static MyClass m_preAllocatedObjects[100];,您实际上并没有定义变量 - 要实际获取变量,您必须执行以下操作:

MyClass MyClasss::m_preAllocatedObjects[100]; 

.cpp 文件中的某处。这是对象的内存被“放置”为数据段中的一个块的地方。所以编译器不必知道MyClass你声明变量时的实际大小。但是,它确实需要知道要评估的大小100 * sizeof(MyClass)

于 2013-07-16T10:18:39.163 回答
3

虽然我无法获得 sizeof(MyClass)?

原因是MyClass直到}类定义结束才完全定义,来自 c++11 标准的第9 节类(n3337 草案):

类名被插入到在看到类名之后立即声明它的作用域中。类名也被插入到类本身的范围内;这被称为注入类名。出于访问检查的目的,注入的类名被视为公共成员名。类说明符通常称为类定义。一个类在看到其类说明符的右大括号后被认为已定义,即使它的成员函数通常尚未定义。可选的属性说明符序列属于类;此后,无论何时命名,attribute-specifier-seq 中的属性都被视为该类的属性。

并且sizeof只能应用于完整类型,来自第5.3.3 节 Sizeof

sizeof 运算符产生其操作数的对象表示中的字节数。操作数要么是一个表达式,它是一个未计算的操作数(第 5 条),要么是一个带括号的类型 ID。sizeof 运算符不得应用于具有函数或不完整类型的表达式、其基础类型在其所有枚举数被声明之前未固定的枚举类型、此类类型的括号名称或指定一个位域。...

要更正,请在类定义之外定义数组的大小:

class MyClass
{
    static char m_preAllocatedMemory[];
};

char MyClass::m_preAllocatedMemory[100 * sizeof(MyClass)];
于 2013-07-16T10:18:33.957 回答
1

您必须分两步执行此操作:

  • 在类中声明一个数组(不知道它的大小)。
  • 定义它,在你完成声明类之后,这样你就知道大小了。

这是代码:

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


char MyClass::m_preAllocatedMemory[100 * sizeof(MyClass)];
于 2013-07-16T10:25:45.647 回答