gpt4 book ai didi

c++ - 重定向 std::cout

转载 作者:IT老高 更新时间:2023-10-28 21:47:47 45 4
gpt4 key购买 nike

我需要一个在其对象的生命周期内将一个 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 社区进行验证。你能在这段代码中发现任何错误或危险吗?

编辑

使不可复制。

最佳答案

这些行相同的原因是因为您所做的是交换 缓冲区。 (也就是说,您通过将原始缓冲区与重定向缓冲区交换来“重定向”;恢复就是交换回来。)

虽然这可能会给您关于输出流的预期效果,但它是不正确的,因为重定向流现在输出到其他地方。 To redirect 表示取一个流并将其输出到其他地方;请注意,这不会影响“其他地方”。

您的类(class)不是重定向;实际上,它应该被命名为 ScopedStreamSwap。例如,试试这个:

#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;

// oops:
filestream << "also to the file, right?...nope" << std::endl;
filestream << "ah, why am i on the screen?!" << std::endl;
}
std::cout << "After redirect." << std::endl;

// in main, return 0 is implicit, if there is no return statement;
// helpful to keep in mind in snippets and short things
}

你想要的是这个:

#include <iostream>
#include <fstream>

class ScopedRedirect
{
public:
ScopedRedirect(std::ostream & inOriginal, std::ostream & inRedirect) :
mOriginal(inOriginal),
mOldBuffer(inOriginal.rdbuf(inRedirect.rdbuf()))
{ }

~ScopedRedirect()
{
mOriginal.rdbuf(mOldBuffer);
}

private:
ScopedRedirect(const ScopedRedirect&);
ScopedRedirect& operator=(const ScopedRedirect&);

std::ostream & mOriginal;
std::streambuf * mOldBuffer;
};


int main()
{
std::cout << "Before redirect." << std::endl;
std::ofstream filestream("redirected.txt");
{
ScopedRedirect redirect(std::cout, filestream);
std::cout << "During redirect." << std::endl;

// yay:
filestream << "also to the file, right?...yes" << std::endl;
filestream << "i am not on the screen" << std::endl;
}
std::cout << "After redirect." << std::endl;

return 0;
}

关于c++ - 重定向 std::cout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4753153/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com