我需要翻译的内容如下:
有没有其他方法可以实现这个?我描述的两种方法有什么问题吗?
我的代码只需要一个头文件,这意味着不应该将声明和定义分割成单独的头文件和源文件。我已经正确地实现了它,并且对于我的用例,它可以按预期工作,其中此头文件仅适用于单个源文件。
现在,当它在多个源文件中使用时(其中有多个.cpp文件包含它),它将失败并出现链接器错误,指出某些变量正在被重新声明。那是因为我的代码像这样-
#ifndef HEADER_HPP
#define HEADER_HPP
....
std::streambuf const *R_coutbuf = std::cout.rdbuf();
std::streambuf const *R_cerrbuf = std::cerr.rdbuf();
std::streambuf const *R_clogbuf = std::clog.rdbuf();
void doSomething(){
[uses if(R_coutbuf) and others]
}
....
#endif HEADER_HPP
现在最好的解决方案是在头文件中声明这些变量,并在单个cpp文件中定义/赋值它们,但正如我所说,我希望能够使用单个头文件完成此操作。这就带来了一个问题,如果多个源文件都包含它,就会出现重新声明的情况。
到目前为止,我还不确定该如何做,但我有两个想法 -
#ifdef DEFINE_VARIABLES
#define EXTERN /* nothing */
#else
#define EXTERN extern int
#endif /* DEFINE_VARIABLES */
EXTERN global_variable = something;
我对此并不十分确定,这样行得通吗?
我思考的第二种方式是将其放入匿名命名空间中,我正在尝试这种方式,目前编译成功 -
#ifndef HEADER_HPP
#define HEADER_HPP
....
namespace R {
namespace {
std::streambuf const *R_coutbuf = std::cout.rdbuf();
std::streambuf const *R_cerrbuf = std::cerr.rdbuf();
std::streambuf const *R_clogbuf = std::clog.rdbuf();
}
void doSomething(){
[uses if(R_coutbuf) and others]
}
}
....
#endif HEADER_HPP
有没有其他方法可以实现这个?我描述的两种方法有什么问题吗?
DEFINE_VARIABLES
/EXTERN
方法可以奏效,只要你在__包含_头文件.hpp_之前,在__确切地__一个_.cpp_文件中定义第一个宏。注意:将您的定义更改为#define EXTERN extern
,因为您可能需要除了int
之外的变量。 - CristiFatinamespace
将在每个翻译单元中生成1个副本。例如,如果您在未命名的namespace
中声明了1个整数,则将为10个.cpp文件生成10个这样的整数。您是否打算这样做?最好使用函数的static
来实现内部链接,如1个答案所建议的那样。 - iammilind