神秘的多重声明

时间:2015-01-17 01:07:59

标签: c++ visual-studio

我有一个名为" controls.h"的文件。声明将在Win32应用程序中使用的按钮的句柄。

#ifndef  CONTROLS_H
#define CONTROLS_H
#include "Window.h"

HWND hwnd_Font_btn;
HWND hwnd_Color_btn;

#pragma region UI_FUNCTION_DEC
bool DrawUI(HWND parenthwnd);
#pragma endregion
#endif

这些句柄和函数声明用于名为" controls.cpp"

的文件中
#include "controls.h"

bool DrawUI(HWND parenthwnd)
{
    hwnd_Font_btn = CreateWindowEx(NULL, L"BUTTON", L"Select Font", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 
        10, 10, 100, 25, parenthwnd, NULL, (HINSTANCE)GetWindowLong(parenthwnd, GWL_HINSTANCE), NULL);
    hwnd_Color_btn = CreateWindowEx(NULL, L"BUTTON", L"Select Color", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
        10, 45, 100, 25, parenthwnd, NULL, (HINSTANCE)GetWindowLong(parenthwnd, GWL_HINSTANCE), NULL);
    return true;
}

" Controls.h"然后包含在" main.cpp"然后调用DrawUI。但是,我无法编译代码,因为Visual Studio表示句柄是在多个位置声明的。

Error   1   error LNK2005: "struct HWND__ * hwnd_Font_btn" (?hwnd_Font_btn@@3PAUHWND__@@A) already defined in controls.obj  D:\Query\Query\main.obj Query
Error   2   error LNK2005: "struct HWND__ * hwnd_Color_btn" (?hwnd_Color_btn@@3PAUHWND__@@A) already defined in controls.obj    D:\Query\Query\main.obj Query

我根本没有看到问题。我承认,我对编程缺乏经验,但Visual Studio的搜索功能显示这些仅用于header和controls.cpp文件。

你能帮我跟踪一下这个问题吗?

2 个答案:

答案 0 :(得分:2)

要在头文件中声明全局变量,您需要在其前面添加extern。然后,您需要在单个源文件(而不是头文件)中定义变量的值。

controls.h

extern HWND hwnd_Font_btn;

controls.cpp

HWND hwnd_Font_btn;

如果省略头文件中的extern,则在每个源文件中定义包含头文件的变量,并且不允许定义多个具有相同名称的变量。

你也可以这样想:

使用extern声明变量告诉链接器,目标文件中的其他位置将有一个具有声明的类型和名称的变量。

不使用extern实际上定义了包含初始值的变量,允许链接器引用与变量关联的内存位置。

答案 1 :(得分:0)

该行的每个实例:

#include "controls.h"

“粘贴”代码中该位置的“controls.h”。

这使得标题中的这些行......

HWND hwnd_Font_btn;
HWND hwnd_Color_btn;

...违反了One Definition Rule

将它们更改为:

extern HWND hwnd_Font_btn;
extern HWND hwnd_Color_btn;

然后在一个cpp文件中定义一次