【问题标题】:Initializing static class members in an initialize function在初始化函数中初始化静态类成员
【发布时间】:2017-02-04 21:44:46
【问题描述】:

我有一个 c++ static 类的私有静态成员(与单例类非常相似,但无需分配类的实例,因为它是自动完成的)。

无论如何,我想初始化这个静态成员。通常,可以通过以下方式解决此问题

例子.h

class Example
{
  private:
    static OtherClass _value;
    Example() {}
};

Example.cpp

#include "Example.h"
OtherClass Example::_value(constructor arguments)

我目前正在编写的代码不允许这样做。本质上,我正在为 OpenGL 编写一个 DebugDraw 类,该类将包含它自己的静态成员,用于创建 OpenGL 着色器的 Shader 对象。如果我用上面的方法,在初始化glew之前会先构建Shader,会造成一些大问题。

这是我正在使用的解决方案。

例子.h

class Example
{
  public:
    Initialize();
  private:
    static OtherClass _value;
    Example(){}
};

Example.cpp

#include "Example.h"

Example::Initialize()
{
  OtherClass _value(constructor arguments)
  // Other code that I will need to add
}

这样编写的代码可以编译,但它会达到我想要的效果(初始化静态类成员)吗?调用 Initialize 函数之前的静态成员是什么意思(我也打算在其中放入一个已初始化的 bool)?

谢谢

这是我正在使用的实际代码。

DebugDraw.h

#ifndef DEBUGDRAW_H
#define DEBUGDRAW_H

#include <GLM\glm\vec4.hpp>

#include "Shader.h"

class DebugDraw
{
  public:
    static void Initialize();
    static void Line();
    static void Triangle();
    static void Box();
    static void Color();
  private:
    static glm::vec4 _color;
    static Shader _shader;
    DebugDraw() {}
};

#endif // !DEBUGDRAW_H

DebugDraw.cpp

#include "DebugDraw.h"

void DebugDraw::Initialize()
{
  glm::vec4 _color(1.0f, 1.0f, 1.0f, 1.0f);
  Shader _shader("Shader/debug.vert", "Shader/debug.frag");
  _shader.Use();
}

^ 这确实可以编译 ^

【问题讨论】:

  • 你确定它可以编译吗?类声明结束后缺少;
  • 是的,这段代码就是一个例子。我不想发布我正在编写的 opengl 代码。我只想知道这件事

标签: c++ opengl static


【解决方案1】:

调用 Initialize 函数之前的静态成员是什么意思(我也打算在其中放入一个已初始化的 bool)?

您正在创建一个名为_val 的局部变量(这应该是_value?),它与您的静态变量无关。因此,您的代码甚至不会链接。


要做你想做的事,你需要初始化变量,就像你在第一个 Example.cpp 中展示的那样,但没有任何构造函数参数:

#include "Example.h"
OtherClass Example::_value;

确保无参数构造函数不执行任何实际初始化!我们将通过创建OtherClass::initialize 方法来延迟此操作。

#include "Example.h"
OtherClass Example::_value;

Example::Initialize()
{
  Example::_value.initialize(...);
}

或者,您可以将 _value 设为指针,将其分配给 NULL 并在需要时将其分配到堆上:

#include "Example.h"
OtherClass *Example::_value = NULL;

Example::Initialize()
{
  Example::_value = new OtherClass(...);
}

当您不再需要它时,不要忘记delete。或者,如果您可以使用 C++11,请改用 std::shared_ptr&lt;OtherClass&gt;

【讨论】:

  • 抱歉,已将_val 编辑为_value。那么这对于第二个实现意味着什么(我在Example::Initialize() 函数中执行静态初始化)?我打算使用在 OtherClass 中有一个 Initialize 函数的方法,但是有一些细节让我不愿意这样做。确实,该类的默认构造函数似乎是个坏主意。
  • 我不确定你在问什么?在第二个实现中,您仍将使用static 变量,但它将是一个指针,并以NULL 开始,直到您将其设置为OtherClass 的实例。
  • 我指的是原始问题中提供的第二个实现。 _value 是在 Example::Initialize() 函数中在堆栈上创建新变量,还是在初始化静态成员 _value。由于它们具有相同的标识符,因此我不确定发生了什么。
  • 啊,谢谢你的澄清。它仍然会在堆栈上创建一个变量。
  • 啊,有道理。感谢您的帮助。
猜你喜欢
  • 2011-07-18
  • 2015-05-18
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多