C++ 正在尝试创建流的错误日志--获取;找到一个或多个多重定义符号;

C++ 正在尝试创建流的错误日志--获取;找到一个或多个多重定义符号;,c++,C++,我正在尝试这样做: #pragma once #include <fstream> #include <string> static std::ofstream ErrorLog; void InitErrorLog(std::string FileName) { ErrorLog.open(FileName); } #pragma一次 #包括 #包括 静态标准::流错误日志; void InitErrorLog(标准::字符串文件名){ ErrorLog.

我正在尝试这样做:

#pragma once
#include <fstream>
#include <string>

static std::ofstream ErrorLog;

void InitErrorLog(std::string FileName) {
    ErrorLog.open(FileName);
}
#pragma一次
#包括
#包括
静态标准::流错误日志;
void InitErrorLog(标准::字符串文件名){
ErrorLog.open(文件名);
}

但是,当在多个CPP文件中包含ing时,我得到一个“找到一个或多个多重定义符号”错误。STL在做什么(提供cout、cin、cerr等——这种方法起源于重定向cerr的一种替代方法)?

您正在打破一个定义规则。您需要使方法
内联

inline void InitErrorLog(std::string FileName) {
    ErrorLog.open(FileName);
}

另外,请注意,通过声明变量
static
,每个翻译单元都有一个副本,即它不是全局变量。要使其全局化,您需要在标题中声明它,并在单个实现文件中定义它。

您正在违反一个定义规则。您需要使方法
内联

inline void InitErrorLog(std::string FileName) {
    ErrorLog.open(FileName);
}
另外,请注意,通过声明变量
static
,每个翻译单元都有一个副本,即它不是全局变量。要使其全局化,您需要在头文件中声明它,并在单个实现文件中定义它。

您正在头文件中为
ErrorLog
提供定义。相反,在源文件中定义它,并在头部保留一个外部声明

来源

std::ofstream ErrorLog;

void InitErrorLog(std::string FileName) {
    ErrorLog.open(FileName);
}
标题

extern std::ofstream ErrorLog;

void InitErrorLog(std::string FileName);
此外,为了将函数保留在头文件中,必须使其
内联
在头文件中提供
ErrorLog
的定义。相反,在源文件中定义它,并在头部保留一个外部声明

inline void InitErrorLog(std::string FileName) {
    ErrorLog.open(FileName);
}
来源

std::ofstream ErrorLog;

void InitErrorLog(std::string FileName) {
    ErrorLog.open(FileName);
}
标题

extern std::ofstream ErrorLog;

void InitErrorLog(std::string FileName);

另外,为了使函数保持在页眉位置,必须使其
内联

@Luchian Grigore:
静态
流不会为每个翻译单元产生不同的实例吗?现在这样更好,因为
错误日志
应该是
外部
,not
static
@Luchian Grigore:not
static
流是否会为每个翻译单元产生不同的实例?现在这更好了,因为
ErrorLog
应该是
extern
,而不是
static
无需编辑文章以包含“解析”文本。简单地接受最好的答案。这就足够了。我正试图避免给那些提供侮辱性答案的人“因果报应”。第二个比第一个好,所以我接受这个。如果你对答案不满意,你不需要接受它们。在你认为可能更好的答案上发表评论,并向他们解释你不满意的原因。@K-ballo的答案在哪方面是“侮辱性的”?在我看来,你接受了一个错误的。没有必要编辑你的文章,包括一个“决议”文本。简单地接受最好的答案。这就足够了。我正试图避免给那些提供侮辱性答案的人“因果报应”。第二个比第一个好,所以我接受这个。如果你对答案不满意,你不需要接受它们。在你认为可能更好的答案上发表评论,并向他们解释你不满意的原因。@K-ballo的答案在哪方面是“侮辱性的”?在我看来,你接受错了。这是我问的第二点,比第一点多得多;我可能应该在发帖前删除这个函数,以免引起过多的关注;我可能应该在发布之前删除这个函数,以避免引起过多的关注。
inline void InitErrorLog(std::string FileName) {
    ErrorLog.open(FileName);
}