我有以下形式的数据结构:
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.isPresentA
和a.isPresentB
中。当a.isPresent
为假时,我的地图a.isPresentA
和a.isPresentB
为空。但是,我看到虽然我没有在a.isPresentA
和a.isPresentB
中存储值,但它的大小仍为104.在C ++中是否有某种方式可以为{{1}分配空间}和a.isPresentA
仅在需要的基础上(即当a.isPresentB
为真时),而不是明确地为它们分配存储空间。
我存储了数百万个A类对象,因此A类的大小是我关心的问题。
我使用的是gcc版本:gcc(Ubuntu / Linaro 4.6.4-6ubuntu2)4.6.4
答案 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
的任何出现