我有以下形式的数据结构:
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
为false时,则映射的a.isPresentA
和a.isPresentB
为空。然而,我看到尽管我没有在a.isPresentA
和a.isPresentB
中存储值,但它的大小仍然是104。C++中是否有某种方法可以使我仅在需要的基础上(即当a.isPresent
为真时)为a.isPresentA
和a.isPresentB
分配空间,而不是显式地为它们分配存储空间。
我正在存储数百万个A类对象,因此A类的大小是我关心的问题
我使用的是gcc版本:gcc(Ubuntu/Linaro 4.6.4-6ubuntu2)4.6.4
创建类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;
};
通过使用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
*/
};
您可能需要用NULL
替换任何出现的nullptr