【发布时间】:2011-01-20 22:02:29
【问题描述】:
我需要一个在其对象的生命周期内将一个 ostream 重定向到另一个 ostream 的类。经过一番修补,我想出了这个:
#include <iostream>
#include <fstream>
class ScopedRedirect
{
public:
ScopedRedirect(std::ostream & inOriginal, std::ostream & inRedirect) :
mOriginal(inOriginal),
mRedirect(inRedirect)
{
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
}
~ScopedRedirect()
{
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
}
private:
ScopedRedirect(const ScopedRedirect&);
ScopedRedirect& operator=(const ScopedRedirect&);
std::ostream & mOriginal;
std::ostream & mRedirect;
};
int main()
{
std::cout << "Before redirect." << std::endl;
std::ofstream filestream("redirected.txt");
{
ScopedRedirect redirect(std::cout, filestream);
std::cout << "During redirect." << std::endl;
}
std::cout << "After redirect." << std::endl;
return 0;
}
它似乎工作正常。然而,奇怪的是,在 构造函数和析构函数中都重复了以下行:
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
我认为这是正确的,但我想与 SO 社区进行验证。您能在这段代码中发现任何错误或危险吗?
编辑使不可复制。
【问题讨论】:
-
+1 - 应该是正确的 - 但如果您根据通用
std::ostream实现逻辑而不是直接调用std::cout会更好。 -
@Billy ONeal:ScopedRedirect 不是已经根据通用 ostream 实现了吗? std::cout 仅在示例中使用。
-
我并不是说你的课不好或不正确。我只是说最好将输出发送到您希望它实际去的地方,而不是在事后重定向它的去向。也就是说,我的意思是应该重构依赖于指向任何特定位置的 std::cout 的代码,而不是更改 cout 指向的位置。
-
@Billy ONeal:啊,我明白了。我绝对同意你的看法。我需要这个类的原因是因为我想关闭由大型遗留代码库产生的调试消息。这是一个(希望是)临时修复。
标签: c++