Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中的头文件中声明全局结构+;_C++_Opengl_Global Variables_Declaration_Structure - Fatal编程技术网

C++ 在C+中的头文件中声明全局结构+;

C++ 在C+中的头文件中声明全局结构+;,c++,opengl,global-variables,declaration,structure,C++,Opengl,Global Variables,Declaration,Structure,我在头文件中创建了一个结构,如下所示: typedef struct { GLfloat lgtR, lgtG, lgtB, lgtA; GLfloat x, y, z; bool islight; GLfloat width, height, depth; GLenum lightn; particle prt; int maxprt; } emitter; 这是毫无问题的 但是,在这个特定的头文件中,我想声明一个全局发射器,它可以在所

我在头文件中创建了一个结构,如下所示:

typedef struct
{
    GLfloat lgtR, lgtG, lgtB, lgtA;
    GLfloat x, y, z;
    bool islight;
    GLfloat width, height, depth;
    GLenum lightn;
    particle prt;
    int maxprt;
} emitter;
这是毫无问题的

但是,在这个特定的头文件中,我想声明一个全局发射器,它可以在所有函数中使用,并且不是主源文件的一部分:

// header.h global declaration

emmiter currentEmit;

GLvoid glSetEmitter(emitter emitter)
{
    currentEmit = emitter;
}
然而,当我尝试这个方法时,我得到了一大堆“error C2228:left of'.variable'必须有class/struct/union,所以我假设它根本没有在这里声明我的结构


是否有一种方法可以在头文件中全局声明该结构,如果有,是否也有一种方法可以防止它成为其他.cpp文件的一部分?

发射器
emmiter
不同

也,因为这是C++——只写代码>结构{{};< /COD>直接,不需要<代码> TyPulf< /C> > /P> 整个标题错误,如果包含在多个翻译单元中,将给出多个定义:

// header.h global declaration
extern emitter currentEmit;   // <-- note extern

inline GLvoid glSetEmitter(emitter emitter)  // <-- note inline
{
    currentEmit = emitter;
}
否则将创建不必要的副本

typedef struct
{
    GLfloat lgtR, lgtG, lgtB, lgtA;
    GLfloat x, y, z;
    bool islight;
    GLfloat width, height, depth;
    GLenum lightn;
    particle prt;
    int maxprt;
} emitter;
最好是

struct Emitter
{
    GLfloat lgtR, lgtG, lgtB, lgtA;
    GLfloat x, y, z;
    bool islight;
    GLfloat width, height, depth;
    GLenum lightn;
    particle prt;
    int maxprt;
};
是否有方法在头文件中全局声明该结构

是的,有两种主要方法可以避免在每个编译单元中创建变量

首先是梅耶斯的单身汉:

namespace g {
    inline Emitter& emitter()
    {
        static Emitter theEmitter;
        return theEmitter;
    }
}

void foo() { g::emitter().x = 666; }
然后是模板化技巧:

namespace detail {
    template< class Dummy >
    struct EmitterVariable
    {
        static Emitter v;
    };

    template< class Dummy >
    Emitter EmitterVariable<Dummy>::v = {};
}

namespace g {
    static Emitter& emitter = EmitterVariable<void>::v;
}

void foo{ g::emitter.x = 666; }
名称空间详细信息{
模板
结构emitter变量
{
静电发射极;
};
模板
发射器EmitterVariable::v={};
}
名称空间g{
静态发射器&发射器=发射器变量::v;
}
void foo{g::emitter.x=666;}
如果是这样的话,有没有办法防止它也成为其他.cpp文件的一部分

是的,上述两种解决方案都可以做到这一点

然而,最后一个将引用注入到每个编译单元中,实际上,它的大小与指针的大小相同


也就是说,全局变量往往会产生非常混乱的数据流。你不知道代码的哪一部分放在那里。你不知道它是否或何时被正确初始化。你不知道如果你在这里更改数据,哪些其他部分会受到影响。或者什么时候。等等。所以这绝对不是一个好主意。全局常量,好的,但全局变量B莱斯,说不就行了™.

哇。真不敢相信我没有意识到这一点。谢谢。至于剩下的,非常有用,谢谢!始终显示第一个错误的全文。在Visual Studio中,这可以在“输出”窗口中找到,而不是在“错误”窗口中找到。
namespace detail {
    template< class Dummy >
    struct EmitterVariable
    {
        static Emitter v;
    };

    template< class Dummy >
    Emitter EmitterVariable<Dummy>::v = {};
}

namespace g {
    static Emitter& emitter = EmitterVariable<void>::v;
}

void foo{ g::emitter.x = 666; }