C ++如何正确使用静态变量?

时间:2019-12-06 07:58:53

标签: c++

我正在制作一个c ++ OpenGL项目,但在使用静态变量时遇到了麻烦。

我有一个标题“ Scene.h”,如下所示:

#pragma once

#include "A.h"

class Scene
{
    //class body
};

static Scene* active = new Scene();

我的A.h文件如下所示:

#pragma once

#include "Scene.h"

class A
{
    active->SomeMethod(); //Here I get error C2065: undeclared identifier
};

在我的源文件中,我只包含了Scene.h,因为它已经包含了A.h,而且我在那没问题。

我还尝试过使用静态场景对象,如下所示:

class Scene
{
    static Scene* active;
};

然后像这样访问它:

Scene::active->DoSomething();

但是然后我收到错误C2653:场景不是类或名称空间名称。我在某处读到要做到这一点,我需要预编译的标头,这对我来说是没有选择的。

在这种情况下拥有静态指针的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

如果在C ++中声明全局变量static,则将其设置为内部链接。这意味着,它对于其他编译单元不可见,并且由于您想在class A中使用它-这可能位于另一个源文件中-这不是您想要的。

您可能想要的是一个静态类成员(第二个示例),但是请注意,除了声明之外,您还需要定义它:

class Scene
{
    public:
       static Scene* active;
};

Scene* Scene::active = new Scene();

还要注意,C ++类的成员默认情况下为 private ,因此您的第二个示例缺少public访问说明符,因此A将无法访问Scene的私人成员。

正如Scheff所指出的那样,您在循环依赖方面遇到了问题。如果class Scene不以任何方式使用A,请在“ Scene.h”中删除#include "A.h"。 否则,将active->SomeMethod();移至class A的实现中,并使用前向声明,而不要在A.h中包括“ Scene.h”。

[edit]注意,由于您仅显示代码摘录: 该答案是在假设您拥有Scene的头文件和源文件以及A的头文件和源文件的前提下编写的。如果仅将SceneA都保留在其标题中,则由于循环依赖关系,事情将无法解决。 除非有充分的理由只使用标头,否则我建议无论如何都应在clas声明(标头文件)和实现(源文件)之间完全分开,如果可能,请避免过多的相互包含,而应使用前向声明

答案 1 :(得分:0)

请参见scheff中的工作示例(通过使用onlineGdb的提示)。

首先,我不建议使用全局变量!更糟糕的是在全局名称空间中使用。更好的设计是在匿名名称空间中使用某些名称空间或(如果适用)(仅从一个文件访问)定义。考虑使用单例模式-但这不能解决您的问题。

第二,我不建议使用原始指针:使用new创建的对象必须销毁,但是到那时您将要这样做。如果您坚持使用指针,请使用一些smartpointer ...-我的增强功能使用Objecte,然后通过cout证明析构函数的调用。

代码中的概率是:您不能在类定义内调用方法。