为什么要在头文件中声明的变量中使用extern

  • 本文关键字:声明 变量 extern 文件 c++
  • 更新时间 :
  • 英文 :


在Visual Studio编译中经常收到LNK2005错误后,我正在深入研究C++头文件,并意识到错误是我在头文件和main.cpp中声明了两次变量,我还发现几个用户给出了如何使用extern type variable_name的解决方案;在头文件中作为解决方案,阅读答案后,我想到了3个问题:

1st-您真的需要使用extern来声明头文件中任何类型的变量吗?如果是这样,为什么不在头文件中声明类时使用它呢?

2nd-在头文件中使用extern是否是一种好的做法?或者有什么更好的东西可以使用,不会给我上面收到的错误?

3rd-根据我所读到的内容,extern的使用要求我也在.cpp文件中重新声明变量,但如果它已经在头文件中声明了,为什么我不能在.cpp中设置它的值?

PS:以下是我彻底研究头文件并在此处生成此问题的原因:

toast通知.h:

#pragma once
bool dollar_value_was_changed;
bool toast_notification_was_created;
void show_toast_notification(), create_and_initialize_toast_notification(), set_toast_notification();
bool is_windows_10();

toast_notification.cpp:

#include "toast_notification.h"
#include <Windows.h>
#include <VersionHelpers.h>
#include <wintoast/wintoastlib.h>
void show_toast_notification()
{
if (is_windows_10())
{
if (!toast_notification_was_created)
create_and_initialize_toast_notification();
}
}
bool is_windows_10()
{
if (IsWindows10OrGreater())
return true;
else
{
MessageBox(NULL, L"Teste", L"Título da janela?", MB_OK);
return false;
}
}
void create_and_initialize_toast_notification()
{
WinToastLib::WinToast::instance()->setAppName(L"Toast Dollar");
WinToastLib::WinToast::instance()->setAppUserModelId(WinToastLib::WinToast::configureAUMI(L"Teste", L"Toast Dollar"));
WinToastLib::WinToast::instance()->initialize();
toast_notification_was_created = true;
}
void set_toast_notification()
{
WinToastLib::WinToastTemplate toast_notification = WinToastLib::WinToastTemplate(WinToastLib::WinToastTemplate::Text02);
toast_notification.setTextField(L"Teste", WinToastLib::WinToastTemplate::FirstLine);
}

main.cpp:

#include "toast_notification.h"
#include <iostream>
int main()
{
std::cout << "Hello World!n";

show_toast_notification();
system("pause");
}

不要太关注代码,我请你把注意力转向变量toast_notification_was_created,在我的脑海中,因为它已经在头文件中声明了,我可以在.cpp中设置它,除此之外,变量dollar_value_was_changed(未使用(也产生了让我问这个问题的错误

错误:

1> toast_notification.obj: error LNK2005: "bool dollar_value_was_changed" (?dollar_value_was_changed @@ 3_NA) already defined in main.obj
1> toast_notification.obj: error LNK2005: "bool toast_notification_was_created" (?doast_notification_was_created @@ 3_NA) already defined in main.obj```

在C++中,命名空间范围内的变量声明是一个定义,除非它被声明为externextern防止声明成为定义。在一个程序中只能定义一次变量(除非将其设为inline(。由于页眉通常包含在多个翻译单元中,因此会得到多个定义。

注意:我不建议使用inlineinline"变量"定义的主要用途是用于constexpr对象。一般来说,我建议不要使用非const全局数据。

最新更新