持久化类变量

时间:2012-08-06 09:32:26

标签: c++ static initialization

我有一个关于静态变量的问题,或者其他一些方法。

我有一个大师班,PatternMatcher。我有几个衍生单位,具体取决于使用的匹配器。现在每个子类都需要存储一个浮点向量,但在每个类中它都是常量。初始化期间会读取该向量的数据,最大可达1GB(最小的是1MB,最大的是1GB)。 目前,当我有两个Matcher_A实例时,它会分配两倍的内存。我事先并不知道使用哪些匹配器(每次运行它将是三个匹配器,并且您可以使用相同的匹配器几次)。我宁愿不在运行时检查所需的匹配器是否已经在某处进行了初始化,因为每次更改都需要额外的代码。

目前我使用

分配3个匹配器
PatternMatcher* a = new PMMatcherA();
PatternMatcher* b = new PMMatcherB();
PatternMatcher* c = new PMMatcherC();

,但由于它们是用户选择的,因此可能发生A和C相同的情况。当我通过typeid(a).name();运行检查时,它会给我PatternMatcher作为结果,从不管我以前用什么类开始。 PatternMatcher基本上只是一个虚拟类。

我一直认为静态意味着变量在不同的分配中是恒定的,但是当我将我的向量定义为静态时,我会得到链接器解析错误。在早期的迭代中,我将这些向量全局化,但是希望将它们本地化到它们的类。

我需要使用哪些关键字让初始化的向量可用于下一次初始化?简单检查矢量大小是否大于0已足够,但每个对象都使用自己的向量。

3 个答案:

答案 0 :(得分:1)

是的,static就是您所需要的。您可以像这样使用它:

class MyClass
{
private:
    static std::vector< float > data_;
};

std::vector< float > MyClass::data_;

请注意,在类本身中,您只能声明静态变量。但是你还需要在类之外定义一次。这就是为什么我们有行std::vector< float > MyClass::data_;,如果省略,你会有链接器错误。

在此之后, MyClass类的每个对象将共享相同的data_向量。

您可以从班级的任何对象操作:

MyClass a;
a.data_.push_back(0);

或通过班级名称:

MyClass::data_.push_back(0);

答案 1 :(得分:1)

static关键字 是一种可行的方式 - 它可以存储整个类的成员的一个副本。您缺少的是在编译模块中实际声明此类静态,以便链接器可以使用它。例如:

header file foo.h

struct Foo {
  static int s_int;
}

source file foo.cpp

#include "foo.h"
int Foo::s_int; // optionally =0 for initialization

第二部分是至关重要的,因为它会为要用作静态成员的对象分配一个内存空间。

但请记住:

  • static成员将全部 main()之前初始化,这意味着无论是否有人使用过,您的1GB数据都将被读取特定班级
  • 您可以解决上述问题,但是您必须检查数据加载和初始化是否在运行时发生

然而,还有另一种选择。如果你按照“原样”(即每个32位,二进制格式)存储浮点数,你可以简单地将文件“映射”到内存空间并像访问它们一样访问它们 - 操作系统将负责加载适当的4K页面在需要时进入RAM。

http://en.wikipedia.org/wiki/Mmap

了解mmap的详情

答案 2 :(得分:1)

  

当我将vector定义为static时,我会得到一个链接器解析器   错误。

这是因为您声明了静态变量(在头文件中),但您从未在其中一个实现文件(.cpp)中显式初始化它。

例如:

//AClass.h 
class AClass
{
    private:
    static std::vector<int> static_vector;

};

并在.cpp实现文件中:

std::vector<int> AClass::static_vector;