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

问题描述 投票:0回答:1

我有一个包含一系列

static
函数的命名空间。片段:

#ifndef CONGREGATION_DATABASE_MANAGER
#define CONGREGATION_DATABASE_MANAGER
#pragma once

namespace CongregationDatabaseManager
{
    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++ visual-c++ namespaces c++20
1个回答
0
投票

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

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

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

最后,说到这样的事情,就涉及到代码组织,这是一项技能。通过使用类及其实例,您通常可以绕过创建全局变量并获得更清晰、更好的代码。 然而有时,特别是在嵌入式编程中,您只想要某个地方的一个变量而不关心。

因此,与其说这是一种正确的技术,不如说这是一种黑客行为。

© www.soinside.com 2019 - 2024. All rights reserved.