我需要定义一个包含环境变量的常量(Linux,g ++)。我更愿意使用string
,但std::getenv
需要*char
(这还不是我的问题)。为避免多重定义错误,我使用了define
解决方法,但这还不够。该计划很简单:DataLocation.hpp
#ifndef HEADER_DATALOCATION_H
#define HEADER_DATALOCATION_H
#include <string>
using namespace std;
const char* ENV_APPL_ROOT = "APPL_ROOT";
[...]
#endif
DataLocation.cpp
:
#include <string>
#include <cstdlib>
#include "DataLocation.hpp"
using namespace std;
// Private members
DataLocation::DataLocation()
{
rootLocation = std::getenv(ENV_APPL_ROOT);
}
[...]
测试程序Test.cpp
#include "DataLocation.hpp"
#include <iostream>
using namespace std;
int main() {
DataLocation *dl;
dl = DataLocation::getInstance();
auto s = dl->getRootLocation();
cout << "Root: " << s << "\n";
}
但是编译时,我收到以下错误:
/tmp/ccxX0RFN.o:(.data+0x0): multiple definition of `ENV_APPL_ROOT'
DataLocation.o:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [Test] Error 1
在我的代码中没有第二个定义,我保护标头不被调用两次。有什么问题?
多重定义问题的典型答案是
在我的案例中,有没有办法将声明和实施分开?
修改1
这个问题与this question无关,因为我的意思是常数。在引用问题的解决方案中,我没有看到如何解决我的问题。
答案 0 :(得分:3)
您要包括两次标题。一次从DataLocation.cpp(它找到HEADER_DATALOCATION_H
尚未定义,因此定义ENV_APPL_ROOT
),一次从Test.cpp(它再次发现HEADER_DATALOCATION_H
尚未定义,从而定义{再次{1}}。“标头保护”仅保护在同一编译单元中多次包含的头文件。
你需要:
ENV_APPL_ROOT
头文件中的和
extern const char* ENV_APPL_ROOT;
在一个.cpp文件中。
答案 1 :(得分:2)
使用
extern const char* ENV_APPL_ROOT;
在头文件中,并放置
const char* ENV_APPL_ROOT = "APPL_ROOT";
在一个特定的翻译单元中(例如DataLocation.cpp
)。
这应该解决它。