首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么静态向量在不同的类中有不同的内容?

为什么静态向量在不同的类中有不同的内容?
EN

Stack Overflow用户
提问于 2015-06-11 08:15:19
回答 3查看 707关注 0票数 3

我有以下代码:

代码语言:javascript
复制
namespace GameStatus{

    static std::vector<SavePoint>savePoints;
}

SavePoint是:

代码语言:javascript
复制
class SavePoint{

public:
    int distance;
    int score;

    SavePoint(int d,int s){
        distance = d;
        score = s;
    };
};

问题是,即使GameStatus::savePointsstatic,该向量似乎包含或不包含元素,这取决于调用类的类型。

例如,如果我有一个类添加了一个保存点:

代码语言:javascript
复制
class Game{

    void addSavePoint(){
        SavePoint savepoint(12,10);
        GameStatus::savePoints.push_back(savepoint);
    }

    void testView(){
       if(!GameStatus::savePoints.empty()){
          Log("There is a save point"); // Can see that savePoints is not empty in the debugger. Everything looks ok here.
       }
    }

}

但如果我还有别的课:

代码语言:javascript
复制
class Foo{
    void something(){
         if(GameStatus::savePoints.empty()){  // In this class it appears that the vector is empty.
              //..do something.
         }
    }
}

我有一个游戏循环,它交替执行游戏和Foo中的代码,在Game中,GameStatus::savePoints有一个savePoint(不是空的),而在Foo中,它没有(看起来是空的)。这对我来说毫无意义,因为savePoints是静态的。因此,两个类都应该访问同一个对象。

如果不同的类,为什么GameStatus::savePoints具有不同的值?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-06-11 08:38:25

static关键字在C++中有两个含义。

  • 在类内 (这是一个面向对象的意思,类似于Java或C# )
  • 存储说明符 (外部类,此类在C中也可用)

解决方案:您应该使用extern存储说明符而不是static将声明放到标头上,因为您希望它是全局的。之后,您应该将定义放到一个.cpp文件中,该文件是一个编译单元/对象。这样,您将有一个向量的实例,它可以从包含标头的所有其他编译单元中访问。

头文件:

代码语言:javascript
复制
namespace GameStatus{
    extern std::vector<SavePoint> savePoints;
}

cpp文件:

代码语言:javascript
复制
    std::vector<SavePoint> GameStatus::savePoints;
票数 1
EN

Stack Overflow用户

发布于 2015-06-11 08:26:47

类之外的static变量仅在当前编译单元中定义(编译单元是正在编译的当前源,即当前源文件及其所有包含的文件)。当您在标头中放置静态变量时,包含该头的每个源文件都会得到自己的副本。

有两种方法可以解决这个问题:

不要使它是静态的-将static关键字更改为“extern”,您将引用一个全局变量。然后,您需要在一个源文件中定义全局变量。例如:

标题:

代码语言:javascript
复制
 extern std::vector<SavePoint>savePoints;

Game.cpp:

代码语言:javascript
复制
 std::vector<SavePoint> GameStatus::savePoints;

2-把它放在类中--类内的静态变量只创建一次。请注意,如果将其放入类中,则需要在标头中声明它,并在单个编译单元中进行定义,否则将得到链接器错误。例如:

标题:

代码语言:javascript
复制
 class Game {
 public:
     std::vector<SavePoint>savePoints;
 }

Game.cpp:

代码语言:javascript
复制
 std::vector<SavePoint> Game::savePoints;
票数 4
EN

Stack Overflow用户

发布于 2015-06-11 08:37:11

相信您将static vector放在头文件中,并包含在GameFoo类中。

所以,你需要首先清楚地理解wt是static的意思。

static变量存在于定义它的翻译单元的“生存期”。

有关更多信息,请参见

正如您在hear中所做的那样,当您包含头部时,将在vector上启动两个单独的实例。所以这两个例子起着明显的作用。这就是为什么如果不同的类,GameStatus::savePoints似乎具有不同的值。

你可以做两件事。

  1. 将向量定义为全局变量。
  2. 你是一个singleton类来包装你的向量.

对于单例,请参考

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30775233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档