gpt4 book ai didi

c++ - 为什么我不能创建流缓冲区的拷贝?

转载 作者:行者123 更新时间:2023-11-28 00:35:20 30 4
gpt4 key购买 nike

当我有这门课时:

class mystreambuf : public std::streambuf
{
public:
mystreambuf(const std::streambuf& other) : std::streambuf(other)
{
}
};

可以编译,但是当我尝试执行此操作时,什么也没有打印出来:

mystreambuf buf(*std::cout.rdbuf());
std::cout.rdbuf(&buf);

std::cout << "Hello";

如果 bufcout 缓冲区的拷贝,为什么它不打印任何内容?

最佳答案

流缓冲区规范中没有任何内容表明如果您以这种方式复制流缓冲区,则拷贝将继续从同一设备读取/写入,也没有指定 cout 使其结果来自 rdbuf() 的行为将如您所愿。

streambuf 本质上是一个接口(interface),它的复制构造函数不会以某种方式虚拟调用任何实现该接口(interface)的类的复制构造函数。不能按值保存、复制、传递等多态类型。为了复制多态类型,您必须使用类似于虚拟 clone() 成员函数的东西,而 streambuf 接口(interface)不包含任何此类方法。

为了复制 cout 使用的 streambuf,你必须使用它的动态类型访问它,即使那样它也可能不可复制:例如,可能是多个流缓冲区访问同一个设备需要以某种方式协调或同步,streambuf 实现可能不允许复制,以便它可以安全地避免必须进行同步。


What I'm trying to do is create a stream buffer with all the characteristics of std::cout's stream buffer, but with extra member functions built in (for my use). Would you know how to do that?

您要添加哪些额外特征?实现 streambuf 可能不是添加功能的合适位置。


如果您想要一个转发到预先存在的流缓冲区的流缓冲区接口(interface)的实现,那么您可以创建一个流缓冲区类,它包含一个流缓冲区指针,将其正确地视为指向多态类型的指针,并通过转发调用来实现流缓冲区接口(interface)到内部streambuf。这是一个非常简单的实现:

#include <iostream>

struct copiable_streambuf : std::streambuf {
std::streambuf *buf; // non-owning pointer

copiable_streambuf(std::streambuf *buf) : buf(buf) {}

std::streambuf::int_type overflow(std::streambuf::int_type c) {
buf->sputc(c);
return 0;
}
};

int main()
{
copiable_streambuf buf (std::cout.rdbuf());
std::ostream os(&buf);
os << "Hello, World!\n";
}

您的示例代码涉及替换 cout 使用的缓冲区。如果你这样做,你应该确保在 cout 在程序结束时被销毁之前将原始缓冲区放回原处,因为 cout 管理它自己的流缓冲区的生命周期并且当 cout 的析构函数运行时,它可能需要它持有的流缓冲区是它最初创建的流缓冲区。

// RAII type for managing buffer switches.
struct buffer_switcher {
std::ostream &os;
std::streambuf *old;

buffer_switcher(std::ostream &os, std::streambuf *buf)
: os(os), old(os.rdbuf())
{
os.rdbuf(buf);
}

~buffer_switcher() { os.rdbuf(old); }
};

int main() {
// create our forwarding buffer
copiable_streambuf buf(std::cout.rdbuf());

// set up cout to use our buffer and simultaneously ensure that the buffer will get switched back as required
buffer_switcher _(std::cout, &buf);

std::cout << "Hello";
}

关于c++ - 为什么我不能创建流缓冲区的拷贝?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21148151/

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