2012-07-02 37 views
2

我有在Utility工具名稱空間中定義的全局變量。這個工具包含在幾個文件中,它看起來是這樣的:避免「已經在......中定義」錯誤/在C++中衝突無類變量

#ifndef _UT_ 
#define _UT_ 
namespace UT { 
    std::string PLATFORM_LINUX_NAME = "linux"; 
    std::string PLATFORM_MACOSX_NAME = "macosx"; 
    std::string PLATFORM_WINDOWS_NAME = "windows"; 
    #if defined(OS_WIN) 
    int PLATFORM = OSTYPE::PLATFORM_WINDOWS; 
    #elif defined(OS_LINUX) 
    int PLATFORM = PLATFORM_LINUX; 
    #elif defined(OS_APPLE) 
    int PLATFORM = PLATFORM_MACOSX; 
    #endif 
}; 

當我包括例如文件阿和bh和Ch這個文件,我得到一個編譯器警告,說:

warning LNK4006: "int UT::PLATFORM" ([email protected]@@3HA) already defined in A.obj; second definition ignored 
warning LNK4006: "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > UT::PLATFORM_LINUX_NAME" ([email protected]@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@A) already defined in A.obj; second definition ignored 

什麼是最好的方式,不涉及創建一個類來解決這個問題? 或者正在創建一個UT類的唯一方法?

+0

你應該知道,開始以下劃線後跟一個大寫字母標識符,如'_UT_',被保留用於編譯器。例如在這個問題中看到詳細信息:http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-ac-identifier –

+0

順便說一下,也許你應該也將它們分組在一個枚舉中,只是爲了清晰起見... –

回答

8

定義單個.cpp文件中的變量並在.h文件中聲明它們。在UT.h

namespace UT 
{ 
    extern const std::string PLATFORM_LINUX_NAME; 
    extern const std::string PLATFORM_MACOS_NAME; 
    extern const std::string PLATFORM_WINDOWS_NAME; 
    extern const int PLATFORM; 
} 

UT.cpp

namespace UT 
{ 
    const std::string PLATFORM_LINUX_NAME = "linux"; 
    const std::string PLATFORM_MACOS_NAME = "macosx"; 
    const std::string PLATFORM_WINDOWS_NAME = "windows"; 

    #if defined(OS_WIN) 
    const int PLATFORM = OSTYPE::PLATFORM_WINDOWS; 
    #elif defined(OS_LINUX) 
    const int PLATFORM = PLATFORM_LINUX; 
    #elif defined(OS_APPLE) 
    const int PLATFORM = PLATFORM_MACOSX; 
    #endif 


} 

我加入const限定符這些似乎是恆定值。

1

一個解決方案是讓它們全部是靜態的,在這種情況下,每個目標文件都有自己的副本。另一種可能性是隻將聲明放在標題中,並將定義放在單獨的文件中。

+0

靜態對非類成員有什麼意義? –

+2

@MihaiTodor靜態在全局範圍內指定內部鏈接。一個未命名的命名空間也可以做到。 – David

+0

@Dave有趣...很高興知道! –

0

嘗試

#ifndef _INCL_GUARD 
#define _INCL_GUARD 

std::string PLATFORM_LINUX_NAME  = "linux"; 
std::string PLATFORM_MACOSX_NAME = "macosx"; 
std::string PLATFORM_WINDOWS_NAME = "windows"; 



#if defined(OS_WIN) 
    int PLATFORM = OSTYPE::PLATFORM_WINDOWS; 
#elif defined(OS_LINUX) 
    int PLATFORM = PLATFORM_LINUX; 
#elif defined(OS_APPLE) 
    int PLATFORM = PLATFORM_MACOSX; 
#endif 

#endif 
+0

我認爲如果他沒有使用最後的#endif,他會從編譯器中得到一個異常... –

+0

@MihaiTodor爲什麼? –

+0

在VS 2010中,intelliSense可以發現它,編譯器提供了一個特定的錯誤:錯誤C1070:文件'test.h'中的錯誤#if /#endif對。我在想,編譯器應該這樣做......我沒有看到一個有效的場景,其中需要/需要在文件中包含#if以及在另一個文件中包含匹配的#endif ... –