持久类变量

Persistent class variables

本文关键字:类变量      更新时间:2023-10-16

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

我有一个大师班,帕特曼彻。根据使用的匹配器,我有几个衍生单元。现在,每个子类都需要存储一个浮点向量,但在每个类中它是常量。该矢量的数据在初始化期间读取,大小可以高达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基本上是一个纯粹的虚拟课堂。

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

我需要使用哪些关键字才能使初始化时的向量可以用于下一次初始化?如果向量大小大于0,只需简单检查就足够了,但每个对象都使用自己的向量。

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中。

有关mmap的更多信息,请访问http://en.wikipedia.org/wiki/Mmap

是的,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);

当我将矢量定义为静态时,我会得到一个链接器解析错误

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

例如:

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

和.cpp实现文件中:

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