在 Visual C++ 中向命名空间添加变量

Adding variables to namespace in Visual C++

提问人:Andrew Truckle 提问时间:8/17/2023 最后编辑:273KAndrew Truckle 更新时间:8/17/2023 访问量:63

问:

我有一个包含一系列函数的命名空间。片段: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
C++ 命名空间

评论

1赞 machine_1 8/17/2023
在什么地方介绍它们,为什么默认情况下它们是只读的?
1赞 Botje 8/17/2023
是什么让您认为“在命名空间中”与“只读”相关?
1赞 molbdnilo 8/17/2023
目前还不清楚是什么阻止了你这样做。命名空间没有什么特别之处。
1赞 BoP 8/17/2023
@Andrew - 如果这是一个头文件,你也应该考虑制作这个函数。否则,您将在包含标头的每个位置获得一个单独的静态函数。inline
1赞 BoP 8/17/2023
是的,那可以做到。

答:

2赞 J.D-g8.1 8/17/2023 #1

您收到多个定义错误,这意味着您多次定义变量或函数。

在头文件中定义变量时,这很容易发生,我猜您正在尝试使用静态来解决这个问题。 从代码中不清楚你在做什么,但如果我猜的话,你正在做这样的事情:

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”仅用于声明。 该变量必须定义在其他地方。

最后,当涉及到这样的事情时,它与代码组织有关,这是一种技能。通过使用它们的类和实例,您通常可以绕过全局变量并获得更清晰、更好的代码。 然而,有时,尤其是在嵌入式编程中,你只想从某个地方得到一个变量,而不在乎。

因此,将其视为一种黑客攻击,而不是一种适当的技术。

顺便说一句。目前还不完全清楚你想做什么,所以我的答案非常基本。看起来您正在尝试从静态的自由函数中返回某些东西的实例。该实例从何而来?

评论

0赞 Andrew Truckle 8/17/2023
为了清楚起见,我将变量插入到 中,因为我意识到它们丢失了,因此造成了混乱。但如前所述,在我的变量(和函数)前面加上前缀就足够了。namespaceinline