简体   繁体   English

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

[英]C++ how to correctly use static variables?

I'm making a c++ OpenGL project and I'm having trouble with static variables.我正在制作一个 c++ OpenGL 项目,但在使用静态变量时遇到了问题。

I have a header "Scene.h" like so:我有一个像这样的标题“Scene.h”:

#pragma once

#include "A.h"

class Scene
{
    //class body
};

static Scene* active = new Scene();

And my Ah file looks like this:我的 Ah 文件如下所示:

#pragma once

#include "Scene.h"

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

In my source file I have included only my Scene.h, since it includes Ah already, and I have no problem there.在我的源文件中,我只包含了我的 Scene.h,因为它已经包含了 Ah,我在那里没有问题。

I have also tried to use a static Scene object like so:我还尝试使用静态 Scene 对象,如下所示:

class Scene
{
    static Scene* active;
};

And then to access it like so:然后像这样访问它:

Scene::active->DoSomething();

But then I get error C2653: Scene is not a class or namespace name.但是后来我收到错误 C2653:场景不是类或命名空间名称。 I read somewhere that to do this I need precompiled headers, and that is no option for me.我在某处读到要做到这一点我需要预编译的头文件,这对我来说是没有选择的。

What is the correct way to have a static pointer in this case?在这种情况下使用静态指针的正确方法是什么?

If you declare a global variable static in C++, you make it internal linkage.如果您在 C++ 中声明一个全局变量static ,您将使其成为内部链接。 This means, it is not visible to other compilation units, and since you want to use it in class A - which probably resides within a different source file - this is not what you want.这意味着,它对其他编译单元不可见,并且由于您想在class A使用它 - 它可能位于不同的源文件中 - 这不是您想要的。

What you probably want is a static class member (your second example), but be aware that in addition to the declaration you need to define it:您可能想要的是静态类成员(您的第二个示例),但请注意,除了声明之外,您还需要定义它:

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

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

Also note that members of C++ classes by default are private , so your second example is lacking the public access specifier, so A would not be able to access a private member of Scene .另请注意,默认情况下 C++ 类的成员是private ,因此您的第二个示例缺少public访问说明符,因此A将无法访问Scene的私有成员。

As Scheff has already pointed, you're having issues with circular dependencies.正如 Scheff 已经指出的那样,您遇到了循环依赖问题。 If class Scene does not use A in any way, remove #include "Ah" in the "Scene.h".如果class Scene不以任何方式使用A ,请删除“Scene.h”中的#include "Ah" ”。 Otherwise move active->SomeMethod();否则移动active->SomeMethod(); to the implementation of class A and use forward declaration instead of including "Scene.h" in Ahclass A的实现并使用前向声明而不是在 Ah 中包含“Scene.h”

[edit] As a note, since you only show excerpts of your code: This answer was written under the assumption that you have a header file and a source file for Scene , and a header file and a source file for A . [编辑] 作为说明,因为您只显示代码的摘录:此答案是在假设您有头文件和源文件Scene以及头文件和源文件A下编写A If you keep both Scene and A within their headers only, things will not work out because of circular dependencies.如果只将SceneA保留在它们的标题中,由于循环依赖,事情将无法解决。 Unless you have a strong reason for going header-only, I would suggest in any case that you have a clean separation between clas declaration (header file) and implementation (source file), avoid too many mutual includes if possible and rather use forward declarations.除非您有充分的理由只使用头文件,否则我建议您在任何情况下都将 clas 声明(头文件)和实现(源文件)明确分开,尽可能避免过多的相互包含,而是使用前向声明.

See working example (by the use of the hint from scheff ) in onlineGdb .见工作示例(通过使用提示从雪夫)在onlineGdb

First of all I do not recommend use of global variables!首先我不推荐使用全局变量! Even worse is there use at global namespace.更糟糕的是在全局命名空间中使用。 Better design is some namespace or if applicable (acessed only from one file) definition in an anonymos namespace.更好的设计是某个命名空间或匿名命名空间中的一些命名空间(如果适用)(仅从一个文件访问)定义。 Think about using the singleton-Pattern - but that does not adress your Question.考虑使用单例模式 - 但这并不能解决您的问题。

Second I do not recomend to use a raw pointer: Objects you created with new you have to destroy, but at which time you'll want to do it.其次,我不建议使用原始指针:使用 new 创建的对象必须销毁,但此时您会想要这样做。 If ever You stick to a pointer use some smartpointer ... - My enhancment uses an Objecte, and prove by cout the call of the destructor.如果你坚持一个指针,使用一些智能指针...... - 我的增强使用一个 Objecte,并通过 cout 证明析构函数的调用。

the Prob in your code is: You can't call a method inside a class definition.代码中的 Prob 是:您不能在类定义中调用方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM