2012-07-11 45 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文件以及?

是的,上述兩個解決方案都是這樣做的。

但是,最後一個注入到每個編譯單元中的引用,其實際上將是指針的大小。

也就是說,全局變量往往會給非常混亂的數據流。你不知道代碼的哪一部分放置了某些東西。您不知道是否或何時正確初始化。如果您在此處更改數據,則不知道哪些其他部分會受到影響。或何時。等等。所以這絕對不是一個好主意。全球常數,行,但全球變量,只是說™。