用C ++组织静态数据

时间:2011-09-23 23:10:54

标签: c++ embedded

我正在开发一些嵌入式软件,其中有一些关于"产品的静态信息"。由于某个产品的信息在执行期间永远不会改变,我想在编译时初始化这些数据结构,以节省堆栈/堆上的一些空间。

我为数据创建了一个Product类,打算在系统中创建大量的所有产品然后在这个结构中进行查找,但我还没弄清楚如何获得它工作。这些阵列给我带来了麻烦。一些伪代码:

class Product {
    int m_price;
    int m_availability[]; // invalid, need to set a size
    ... etc

    // Constructor grabbing values for all members
    Product(int p, int a[], ...);
}

static const Product products[] = 
{
    Product(99, {52,30,63, 49}, ...), // invalid syntax
    ...                    
}                     

有没有办法制作像这样的作品?我唯一能想到的就是按属性进行组织并跳过整个Product对象。我觉得这会让整个事情更难理解和维护。

有没有人对如何最好地组织这类数据有任何建议?

谢谢。

4 个答案:

答案 0 :(得分:4)

古老的C风格静态结构阵列听起来非常符合您的要求。在编译时初始化,零运行时开销,不使用堆栈或堆。 C仍然是嵌入式世界的主要参与者并非共同发生。

所以(一个配方 - 有足够的空间来改变这个细节);

// in .h file
    class Product {
    public: // putting this first means the class is really a struct
        int m_price;
        int m_availability[4]; 
        //.... (more)
    };
    extern const Product product_array[];
    extern const int     product_array_nbr;

// in .cpp file
    const Product product_array[] =
    {
        {
             23,
             {56,1,2,4},
             //....(more)
        },
        {
             24,
             {65,1,2,4},
             //....(more)
        },
        //....(more)
    };

    const int product_array_nbr = sizeof(product_array)/sizeof(product_array[0]);

答案 1 :(得分:2)

几年前,当我在嵌入式工作时,我们需要明确控制结构的内存分配。

想象一下这种结构:

.h文件

template<class T,uint16 u16Entries>
class CMemoryStruct
{
public:
    /**
    *Default c'tor needed for every template
    */
    CMemoryStruct(){};
    /**
    *Default d'tor
    */
    ~CMemoryStruct(){};
    /**
    *Array which hold u16Entries of T objects. It is defined by the two template parameters, T can be of any type
    */
    static T aoMemBlock[u16Entries];
    /**
    *Starting address of the above specified array used for fast freeing of allocated memory
    */
    static const void* pvStartAddress;
    /**
    *Ending address of the above specified array used for fast freeing of allocated memory
    */
    static const void* pvEndAddress;
    /**
    *Size of one T object in bytes used for determining the array to which the necessary method will be invoked
    */
    static const size_t sizeOfEntry;
    /**
    *Bitset of u16Entries which has the same size as the Array of the class and it is used to specify whether
    *a particular entry of the templated array is occupied or not
    */
    static std::bitset<u16Entries> oVacancy;
};


/**
*Define an array of Type[u16Entries]
*/
template<class Type,uint16 u16Entries> Type CMemoryStruct<Type,u16Entries>::aoMemBlock[u16Entries];
/**
*Define a const variable of a template class
*/
template<class Type,uint16 u16Entries> const void* CMemoryStruct<Type,u16Entries>::pvStartAddress=&CMemoryStruct<Type,u16Entries>::aoMemBlock[0];
template<class Type,uint16 u16Entries> const void* CMemoryStruct<Type,u16Entries>::pvEndAddress=&CMemoryStruct<Type,u16Entries>::aoMemBlock[u16Entries-1];
template<class Type,uint16 u16Entries> const size_t CMemoryStruct<Type,u16Entries>::sizeOfEntry=sizeof(Type);
/**
*Define a bitset inside a template class...
*/
template<class Type,uint16 u16Entries> std::bitset<u16Entries> CMemoryStruct<Type,u16Entries>::oVacancy;

根据您的编译器和环境,您可以操纵静态分配所在的区域。在我们的例子中,我们把它移到了很多的ROM上。另请注意,根据您的编译器(即Greenhills编译器),您可能需要使用export关键字并将静态成员定义为.cpp文件。

您可以使用开始和结束指针来浏览数据。如果您的编译器支持完整的STL,您可能希望将std :: vectors与自定义分配器和重载的新运算符一起使用,这样可以将内存保存到堆栈以外的其他位置。在我们的例子中,新的运算符被重载,所有内存分配都是在预定义的内存结构上完成的。

希望我能给你一个想法。

答案 2 :(得分:1)

在C ++ 98/03中,无法在构造函数初始值设定项中初始化数组。

在C ++ 11中,已经通过统一初始化修复了这个问题:

class Product
{
  int m_availability[4]; 
public:
  Product() : m_availability{52,30,63, 49} { }
};

如果您需要在构造函数中提供数据,请改为使用vector

class Product
{
  const std::vector<int> m_availability; 
public:
  Product(std::initializer_list<int> il) : m_availability(il) { }
};

用法:

extern const Product p1({1,2,3});

答案 3 :(得分:0)

当代码实际执行时,静态变量的内存仍然保留 - 您不会在堆栈上节省空间。您可能需要考虑使用向量而不是数组 - 它们更容易传递和处理。