如果.h文件在多个.cpp文件中被包含,那么结构体会失效吗?

3

我希望在多个.cpp文件中使用callbacks对象,但如果我多次引用它,VS会报错"找到一个或多个多次定义的符号"

#ifndef HEADER_H
#define HEADER_H

typedef struct {
void(__cdecl *callbackOne)(bool val);
void(__cdecl *callbackTwo)(bool val);
void(__cdecl *callbackThree)(bool val);
} Callbacks;
Callbacks callbacks;

#endif

2
你应该了解“声明”和“定义”的区别。 - too honest for this site
想一想:当你在多个源文件中包含头文件时,你会将头文件内容(一次)复制到它们中。多个结构体描述不是问题,但对象回调因为这是全局可见的,链接对象文件会发现这个冲突。 - Youka
2个回答

2
Callbacks callbacks;

这是一个定义。因为 #include 像文本替换一样工作,在包含您的头文件的每个源文件中,都将定义一个(单独、不同的)结构实例。
因此,当最终将编译后的目标文件链接在一起时,每个目标文件都包含一个自己的实例和相关的符号 callbacks,导致了上述的链接错误。
要想拥有一个单一的结构实例,您需要将上面的定义放入一个单独的源文件中。
为了能够从其他源文件中使用该实例,它们需要能够引用它(“知道它的名字”)。这就是声明的目的(“给出一个名称”):
extern Callbacks callbacks;

这是您需要放入页眉的内容。

在我的头文件中,extern Callbacks callbacks; 和在源文件中的 typedef struct {...} Callbacks;Callbacks callbacks; 似乎会导致回调函数的重定义错误。 - theman
2
谁告诉你要在源文件中放置 typedef struct ...?将 typedef 放在头文件中,将 extern Callbacks callbacks; 放在头文件中,将 Callbacks callbacks; 放在源文件中。如果仍然无法工作,请发布您的新代码。最重要的是要理解定义和声明之间的区别。 - john
谢谢!那就是问题所在。 - theman

0
在头文件中声明。
extern Callbacks callbacks;

并在某个cpp文件中定义对象。

Callbacks callbacks;

否则,如果有多个cpp文件包含此头文件,则该对象将有多个定义。

错误 C2086:'int callbacks':重定义。在某个cpp文件中定义对象时出现了此错误。 - theman
@theman 这只意味着你在其他cpp文件中也定义了该对象。你应该按照我所描述的做。 - Vlad from Moscow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接