我正致力于用 C++ 制作游戏。我已经声明了一个常量命名空间,用于我需要在整个程序中访问的全局值。在那里我有一个用于调试目的的 ofstream(是的,我知道它不是“常量”但它最适合那里),它只在需要时输出。我能够制作一个小程序来演示这个问题。对于它分布在 4 个文件中,我深表歉意,但我保证这很重要。
主要.cpp:
// Include necessary files
#include "test.h"
#include "constants.h"
#include <fstream>
using namespace std;
int main(int argc, char* argv[])
{
// Start of program
Constant::outstream.open("test.txt");
// ...
// Do stuff
// Output debugging info
Test test;
test.print("Test", Constant::outstream);
// ...
// Do other stuff
// End of program
Constant::outstream.close();
return 0;
}
常量.h:
#ifndef _CONSTANTS_H
#define _CONSTANTS_H
#include <fstream>
namespace Constant
{
static ofstream outstream;
}
#endif
测试.h:
#ifndef _TEST_H
#define _TEST_H
#include <string>
#include <fstream>
#include "constants.h"
class Test
{
public:
void print(string str, ofstream& out);
};
#endif
测试.cpp:
#include "test.h"
using namespace std;
void Test::print(string str, ofstream& out)
{
out << "out: " << str << endl << flush; // Works
Constant::outstream << "Constant::outstream: " << str << endl << flush; // Doesn't
}
在 test.cpp 文件中,out << ...
行正常工作,而 Constant::outsream << ...
即使我正在通过 Constant::outstream
行也没有做任何事情作为 out
范围!我看不出为什么这两行应该有任何不同。
在发布之前,我尝试将 test.cpp 的代码放在 test.h 中,只是为了减少问题的文件,并且惊讶地看到它有效。如果我复制粘贴 Test::print()
函数进入 test.h(无论是在 class Test { ... }
内部还是外部),然后两个输出命令都可以正常工作。只有在 Test::print()
时才会出现问题的实现在一个单独的文件中。
似乎对 Constant::outstream
的任何引用根本不能在类 cpp 文件中工作(没有编译错误,什么也没有发生)。它适用于 main.cpp 和类头文件,但似乎不适用于任何类 cpp 文件。不幸的是,这是我正在编写的一个大程序,几乎每个类都有自己的 cpp 实现文件,而这正是我需要使用这个 ofstream 的地方。有谁知道这是什么原因?
提前致谢,
道格
最佳答案
Constant::outstream
具有内部链接,因此为每个翻译单元创建一个单独的实例。总之,test.cpp和main.cpp中的Constant::outstream
是两个不同的变量。
§3.5.2 具有 namespace 范围 (3.3.6) 的名称如果是以下名称,则具有内部链接 — 显式声明为静态的变量、函数或函数模板;或者,
另一方面,静态类成员在整个程序中都是可见的。 所以,如果你会写
struct Constant
{
static ofstream outstream;
}
代替
namespace Constant
{
static ofstream outstream;
}
它会起作用。
但是要注意类必须有外部链接;例如你不应该放在匿名命名空间中。
关于C++ 命名空间 ofstream 不会写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23178664/