在C ++中根据需要为数据结构分配空间

时间:2015-03-20 10:24:07

标签: c++

我有以下形式的数据结构:

class A{
    unsigned t;
    bool isPresent;
    map<unsigned,unsigned> isPresentA;
    map<unsigned,unsigned> isPresentB; 
};

int main(int argc, char** argv) {
    A a;
    cout<<"size of map="<<sizeof(a)<<"\n";
    return 0;
}

现在a.isPresent为真,那么我只会将值存储在a.isPresentAa.isPresentB中。当a.isPresent为假时,我的地图a.isPresentAa.isPresentB为空。但是,我看到虽然我没有在a.isPresentAa.isPresentB中存储值,但它的大小仍为104.在C ++中是否有某种方式可以为{{1}分配空间}和a.isPresentA仅在需要的基础上(即当a.isPresentB为真时),而不是明确地为它们分配存储空间。

我存储了数百万个A类对象,因此A类的大小是我关心的问题。

我使用的是gcc版本:gcc(Ubuntu / Linaro 4.6.4-6ubuntu2)4.6.4

2 个答案:

答案 0 :(得分:1)

创建A类实例时,会自动分配这两个映射。为了解决这个问题,你可以指出它们:

class A{
    unsigned t;
    bool isPresent;
    map<unsigned,unsigned>* isPresentA;
    map<unsigned,unsigned>* isPresentB; 
};

但是,你现在需要自己分配(并删除!)!更安全的选择是使用std :: shared_ptr:

class A{
    unsigned t;
    bool isPresent;
    std::shared_ptr<map<unsigned,unsigned>> isPresentA;
    std::shared_ptr<map<unsigned,unsigned>> isPresentB; 
};

您仍然需要初始化它们,但至少您不必担心删除它们。您应该在类中添加构造函数或初始化函数来执行此操作:

class A{
    A(bool is_present) {
        isPresent = is_present;
        if (isPresent) {
            isPresentA = std::make_shared<map<unsigned int, unsigned int>>();
            isPresentB = std::make_shared<map<unsigned int, unsigned int>>();
        }
    }
    unsigned t;
    bool isPresent;
    std::shared_ptr<map<unsigned,unsigned>> isPresentA;
    std::shared_ptr<map<unsigned,unsigned>> isPresentB; 
};

答案 1 :(得分:1)

通过使用unique_ptr:

,您可以实现您想要的而不会使您的课程复杂化
#include <map>
#include <memory>

class A {
    unsigned t;
    unique_ptr<map<unsigned, unsigned>> isPresentA;
    unique_ptr<map<unsigned, unsigned>> isPresentB;
};

您可以直接使用isPresentA或B来检查是否存在:

if (a.isPresentA) {
}

或将其包装到某个类方法alla bool isPresent();

更精致的版本可能如下所示:

#include <memory>
#include <map>

using namespace std;


class A {
    struct OptinalParts {
        map<unsigned, unsigned> a;
        map<unsigned, unsigned> b;
    };
    unsigned t;
    unique_ptr<OptinalParts> optional;

public:
    A() :t(0),optional(nullptr){};
    A(bool initState):t(0) {
        makePresent(initState);
    }
    bool isPresent() {
        return (bool)optional;
    }
    void makePresent(bool set) {
        if (set && !isPresent())  {             
            optional.reset(new OptinalParts);                   
        }
        else {
            optional.reset(nullptr); 
        }
    }
    /*
    * accessors
    */
};

您可能需要nullptr

替换NULL的任何出现