我在头文件中创建了一个结构,如下所示:
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,所以我假设它根本没有声明我的结构。< / p>
有没有办法在头文件中全局声明该结构,如果是这样,是否还有办法阻止它成为其他.cpp文件的一部分?
答案 0 :(得分:7)
emitter
与emmiter
不同。
此外,由于这是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;
}
否则将创建不必要的副本。
答案 1 :(得分: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文件的一部分吗?
是的,上述两种解决方案都是这样做的。
然而,最后一个为每个编译单元注入一个引用,实际上它将是指针的大小。
尽管如此,全局变量往往会产生非常混乱的数据流。你不知道代码的哪一部分放在那里。您不知道它是否或何时正确初始化。如果您在此处更改数据,则不知道哪些其他部分会受到影响。或者何时。等等。所以这绝对不是一个好主意。全局常量,好的,但全局变量,Just Say No™。