c++ - 避免为单个 header 重新定义变量

标签 c++ c++11 namespaces extern

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

现在,当涉及到它在多个源文件(其中包含多个 .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

还有其他方法可以实现吗?我上面描述的任何一种方式是否有任何问题。

最佳答案

你可以让你的变量成为函数中的局部静态变量:

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

关于c++ - 避免为单个 header 重新定义变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39450809/

相关文章:

c++ - Qt 连接一个 ui 成员和同一连接中的两个信号

c++ - C++11 的移动语义是否优于写时复制习惯用法?

C++使用lambda进行隐式构造函数调用,期望函数指针

vb.net - 修复 'Error class is ambiguous in the namespace' 保持其模糊性

c++ - 在 C++ 中找不到窗口

C++ 高亮错误?

namespaces - TCL中命名空间/上级/全局的使用

java - 如何将 xml 命名空间添加到 Java 中的非根元素?

c++ - 在遵循 pimpl 设计模式的类中实现移动语义的正确方法是什么?

c++ - 获取 std::tuple 的一部分