在类成员声明中获取sizeof(MyClass)

时间:2013-07-16 10:10:38

标签: c++ static sizeof

我在嵌入式C ++项目中工作,我计划尽可能多地静态分配内存。所以,我正在编写一组函数来覆盖所有类和全局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)?

3 个答案:

答案 0 :(得分:3)

  

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

原因是MyClass在类定义的结束}之前没有完全定义,来自c ++ 11标准的 9 Classes 部分(草案n3337) ):

  

在看到类名后立即将类名插入到作用域中。   类名也插入到类本身的范围内;这被称为注入类名。   出于访问检查的目的,inject-class-name被视为公共成员名称。一个   class-specifier通常称为类定义。 关闭后会考虑定义一个类   已经看到它的类说明符的大括号,即使它的成员函数一般尚未定义。   可选的attribute-specifier-seq属于该类; attribute-specifier-seq中的属性是   之后,只要它被命名,就会考虑该类的属性。

sizeof只能应用于完整类型,部分 5.3.3 Sizeof

  

sizeof运算符产生其操作数的对象表示中的字节数。操作数是   表达式,它是未评估的操作数(第5条)或带括号的type-id。 sizeof   运算符不应该应用于具有功能或不完整类型的表达式到枚举   在声明所有枚举数之前,其基础类型未修复的类型为括号   此类型的名称,或指定位字段的左值。 ...

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

class MyClass
{
    static char m_preAllocatedMemory[];
};

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

答案 1 :(得分:3)

要“知道”编译器需要知道整个类的MyClass的大小。当你向前声明static MyClass m_preAllocatedObjects[100];时你实际上没有定义变量 - 要实际获得变量,你必须这样做:

MyClass MyClasss::m_preAllocatedObjects[100]; 

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

答案 2 :(得分:1)

你必须分两步完成:

  • 在类中声明一个数组(不知道它的大小)。
  • 在你完成声明课程后定义它,以便你知道它的大小。

以下是代码:

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


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