提问人:Andrew Truckle 提问时间:8/17/2023 最后编辑:273KAndrew Truckle 更新时间:8/17/2023 访问量:63
在 Visual C++ 中向命名空间添加变量
Adding variables to namespace in Visual C++
问:
我有一个包含一系列函数的命名空间。片段:static
#ifndef CONGREGATION_DATABASE_MANAGER
#define CONGREGATION_DATABASE_MANAGER
#pragma once
namespace CongregationDatabaseManager
{
int iEditMenuID;
int iDeleteMenuID;
static const COLORREF GetAssignedTextColour()
{
return theApp.GetNumberSetting(L"Options", L"AssTextColour", PALETTERGB(0, 0, 255));
}
}
#endif
我正在努力思考如何引入这两个变量:
int iEditMenuID;
int iDeleteMenuID;
但我不希望它是只读的,因为我需要能够更新值。
当我将变量引入命名空间时,我收到链接错误:
7>CongregationOptionsDlg.obj : error LNK2005: "int CongregationDatabaseManager::iLocalEditMenuId" (?iLocalEditMenuId@CongregationDatabaseManager@@3HA) already defined in CongregationDlg.obj
7>CongregationOptionsDlg.obj : error LNK2005: "int CongregationDatabaseManager::iLocalDeleteMenuId" (?iLocalDeleteMenuId@CongregationDatabaseManager@@3HA) already defined in CongregationDlg.obj
7>CongregationSpeakerDlg.obj : error LNK2005: "int CongregationDatabaseManager::iLocalEditMenuId" (?iLocalEditMenuId@CongregationDatabaseManager@@3HA) already defined in CongregationDlg.obj
7>CongregationSpeakerDlg.obj : error LNK2005: "int CongregationDatabaseManager::iLocalDeleteMenuId" (?iLocalDeleteMenuId@CongregationDatabaseManager@@3HA) already defined in CongregationDlg.obj
7>ChristianLifeMinistryStudentMaterialDlg.obj : error LNK2005: "int CongregationDatabaseManager::iLocalEditMenuId" (?iLocalEditMenuId@CongregationDatabaseManager@@3HA) already defined in CongregationDlg.obj
7>ChristianLifeMinistryStudentMaterialDlg.obj : error LNK2005: "int CongregationDatabaseManager::iLocalDeleteMenuId" (?iLocalDeleteMenuId@CongregationDatabaseManager@@3HA) already defined in CongregationDlg.obj
7>Meeting Schedule Assistant.obj : error LNK2005: "int CongregationDatabaseManager::iLocalEditMenuId" (?iLocalEditMenuId@CongregationDatabaseManager@@3HA) already defined in CongregationDlg.obj
7>Meeting Schedule Assistant.obj : error LNK2005: "int CongregationDatabaseManager::iLocalDeleteMenuId" (?iLocalDeleteMenuId@CongregationDatabaseManager@@3HA) already defined in CongregationDlg.obj
7>Meeting Schedule AssistantDlg.obj : error LNK2005: "int CongregationDatabaseManager::iLocalEditMenuId" (?iLocalEditMenuId@CongregationDatabaseManager@@3HA) already defined in CongregationDlg.obj
7>Meeting Schedule AssistantDlg.obj : error LNK2005: "int CongregationDatabaseManager::iLocalDeleteMenuId" (?iLocalDeleteMenuId@CongregationDatabaseManager@@3HA) already defined in CongregationDlg.obj
7>WeekendMeetingDlg.obj : error LNK2005: "int CongregationDatabaseManager::iLocalEditMenuId" (?iLocalEditMenuId@CongregationDatabaseManager@@3HA) already defined in CongregationDlg.obj
7>WeekendMeetingDlg.obj : error LNK2005: "int CongregationDatabaseManager::iLocalDeleteMenuId" (?iLocalDeleteMenuId@CongregationDatabaseManager@@3HA) already defined in CongregationDlg.obj
7>PublishersDatabaseDlg.obj : error LNK2005: "int CongregationDatabaseManager::iLocalEditMenuId" (?iLocalEditMenuId@CongregationDatabaseManager@@3HA) already defined in CongregationDlg.obj
7>PublishersDatabaseDlg.obj : error LNK2005: "int CongregationDatabaseManager::iLocalDeleteMenuId" (?iLocalDeleteMenuId@CongregationDatabaseManager@@3HA) already defined in CongregationDlg.obj
7>D:\My Programs\2022\MeetSchedAssist\Meeting Schedule Assistant\Release\Meeting Schedule Assistant.exe : fatal error LNK1169: one or more multiply defined symbols found
答:
您收到多个定义错误,这意味着您多次定义变量或函数。
在头文件中定义变量时,这很容易发生,我猜您正在尝试使用静态来解决这个问题。 从代码中不清楚你在做什么,但如果我猜的话,你正在做这样的事情:
namespace WhatEver {
int VariableForCountingThatIWantToReachGlobally = 10;
}
问题是,在这样做时,是
int WhatEver::VariableForCounting = 10;
将在包括标头在内的每个文件中定义。你得到重复,所以你的编译器说“嘿!我不认为这是你想要的?
默认情况下,任何未声明为 static 的变量都是 extern,这意味着可以从所有翻译单元访问它(简化:您的其他 .cpp 文件)
我猜你想要的是一个可以从任何地方访问的变量?
有多种方法可以实现这一点,使这种棘手的原因在于您不想复制变量。 一个简单的解决方案 - 不一定是一个好的解决方案 - (代码容易出错,难以维护和理解等) 所以要注意。:)
--在 .cpp 文件 1 中:--
int MyGlobal = 10;
--在 .cpp 文件 2 中:--
extern int MyGlobal;
// this tells the compiler/linker: "don't worry!, i promise MyGlobal does exist somewhere!
//this could also be in a namespace
extern int WhateverSpace::MyGlobodoid;
-- 就是这样,使用此解决方案,您永远不会在标头中提及变量名称,并且您必须意识到“extern”仅用于声明。 该变量必须定义在其他地方。
最后,当涉及到这样的事情时,它与代码组织有关,这是一种技能。通过使用它们的类和实例,您通常可以绕过全局变量并获得更清晰、更好的代码。 然而,有时,尤其是在嵌入式编程中,你只想从某个地方得到一个变量,而不在乎。
因此,将其视为一种黑客攻击,而不是一种适当的技术。
顺便说一句。目前还不完全清楚你想做什么,所以我的答案非常基本。看起来您正在尝试从静态的自由函数中返回某些东西的实例。该实例从何而来?
评论
namespace
inline
评论
inline