2012-07-11 43 views
0

我创建了一个头文件的结构如下:声明在头文件中的全球结构在C++

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

然而,当我做试试这个,我得到了很多“错误C2228:'.variable'左边必须有class/struct/union,所以我假设它根本没有在这里声明我的结构

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

+0

总是显示第一个错误的全文。在Visual Studio中,在“输出”窗口中可以找到它,而在“错误”窗口中可以找到*不*。 – 2012-07-11 16:17:53

回答

7

emitteremmiter不一样。

此外,由于这是C++ - 直接编写struct {};,不需要typedef

你的整个头是错误的,如果包括在多个翻译单位将给予多重定义:

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

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

currentEmit需要在一个单一的实现文件,而不是一个标题来定义。该功能需要为inline,因此它不是由所有TU定义的。

最后一件事:通过const引用传递参数:

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

否则不必要的副本将被创建。

+0

哇。不能相信我没有接受。谢谢。至于其余的,非常有用,谢谢! – 2012-07-11 16:17:46

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

,如果是这样,有也是一种方式,以保持它被部分其他.cpp文件以及?

是的,上述两个解决方案都是这样做的。

但是,最后一个注入到每个编译单元中的引用,其实际上将是指针的大小。

也就是说,全局变量往往会给非常混乱的数据流。你不知道代码的哪一部分放置了某些东西。您不知道是否或何时正确初始化。如果您在此处更改数据,则不知道哪些其他部分会受到影响。或何时。等等。所以这绝对不是一个好主意。全球常数,行,但全球变量,只是说™。