简体   繁体   English

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

[英]Declaring global structures in header files in C++

I've created a structure in a header file as follows: 我在头文件中创建了一个结构,如下所示:

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

which works without a problem. 可以正常工作。

However, in that particular header file, I want to declare a global emitter that I can use in all the functions and isn't part of the main source file: 但是,在该特定的头文件中,我想声明一个可以在所有函数中使用的全局发射器,它不属于主源文件:

// header.h global declaration

emmiter currentEmit;

GLvoid glSetEmitter(emitter emitter)
{
    currentEmit = emitter;
}

However, when I do try this, I get a whole lot of "error C2228: left of '.variable' must have class/struct/union, so I'm assuming it's not declaring my structure here at all. 但是,当我尝试这样做时,出现了很多“错误C2228:'。variable'的左边必须有class / struct / union,所以我假设它根本不在这里声明我的结构。

Is there a way to declare that structure globally within a header file, and if so, is there also a way to keep it from being part of the other .cpp files as well? 是否可以在头文件中全局声明该结构,如果可以,是否还可以使它不成为其他.cpp文件的一部分?

emitter is not the same as emmiter . emitteremitter emmiter

Also, since this is C++ - just write struct {}; 另外,由于这是C ++,因此只需编写struct {}; directly, there's no need for a typedef . 直接地,不需要typedef

Your whole header is wrong, and will give multiple definitions if included in multiple translation units: 您的整个标头是错误的,如果包含在多个翻译单元中,则会给出多个定义:

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

inline GLvoid glSetEmitter(emitter emitter)  // <-- note inline
{
    currentEmit = emitter;
}

currentEmit needs to be defined in a single implementation file, not a header. currentEmit需要在单个实现文件中定义,而不是在标头中定义。 The function needs to be inline so it's not defined by all TU. 该功能需要inline因此并非所有TU都定义。

Last thing: pass the parameter by const reference: 最后一件事:通过const引用传递参数:

inline GLvoid glSetEmitter(const emitter& emitter)  // <-- note inline
{
    currentEmit = emitter;
}

Otherwise an unnecessary copy will be created. 否则,将创建不必要的副本。

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

should better be 最好是

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

Is there a way to declare that structure globally within a header file, 有没有办法在头文件中全局声明该结构,

Yes, there are two main ways to avoid the variable being created in each compilation unit. 是的,有两种主要方法可以避免在每个编译单元中创建变量。

First there is the Meyers' singleton: 首先是迈耶斯单身人士:

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

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

Then there is the templatization trick: 然后是模板化技巧:

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; }

and if so, is there also a way to keep it from being part of the other .cpp files as well? 如果是的话,还有没有办法使它也不会成为其他.cpp文件的一部分?

Yes, both of the above solutions do that. 是的,以上两种解决方案都可以做到这一点。

The last one, however, injects a reference into each compilation unit, which in practice will be the size of a pointer. 但是,最后一个将引用插入每个编译单元,实际上这将是指针的大小。

That said, global variables tend to give very messy data flows. 也就是说,全局变量倾向于提供非常混乱的数据流。 You don't know which part of the code put something there. 您不知道代码的哪一部分将内容放置在那里。 You don't know if or when it's properly initialized. 您不知道是否或何时正确初始化了它。 You don't know which other parts will be affected if you change data here. 如果您在此处更改数据,则不知道其他哪些部分会受到影响。 Or when. 或何时。 And so on. 等等。 So it's absolutely not a good idea. 因此,这绝对不是一个好主意。 Global constants , OK, but global variables , Just Say No™. 全局常数 ,可以,但是全局变量 ,只需说“否”。

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

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