避免重新定义单个标头的变量

Abh*_*yal 6 c++ namespaces extern c++11

我对代码有一个标头要求,这意味着不应该将声明和定义拆分成单独的头文件和源文件.我已经正确地实现了它并且它按照我的用例的预期工作,其中此头文件仅包含在单个源文件中.

现在,当涉及到它在多个源文件中使用时(多个.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
Run Code Online (Sandbox Code Playgroud)

现在最好的解决方案是在头文件中声明这些变量并在单个cpp文件中定义/分配它们,但正如我所说,我希望能够使用单个头文件执行此操作.这带来了问题,如果多个源文件将包含它,将会有重新声明.

到目前为止,我不知道我应该怎么做才能做到这一点,但我有两个想法 -

#ifdef DEFINE_VARIABLES
#define EXTERN /* nothing */
#else
#define EXTERN extern int
#endif /* DEFINE_VARIABLES */

EXTERN global_variable = something;
Run Code Online (Sandbox Code Playgroud)

我不是很确定,这甚至会起作用吗?

我想到的第二种方法是将它放在一个匿名的命名空间中,我正在尝试这个并且到目前为止它的构建成功 -

#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
Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以达到这个目的?我上述任何一种方式都有问题.

Chr*_*rew 5

您可以在函数中使变量成为局部静态变量:

inline std::streambuf const*& R_coutbuf() {
    static std::streambuf const* b = std::cout.rdbuf();
    return b;
}
Run Code Online (Sandbox Code Playgroud)