我有一个程序(游戏),它设计成通过键盘从人类用户那里接收输入。然而,在某些时候,我希望从用户那里夺取控制权,并为他们做出某些决定。虽然可以编写特殊情况代码以模拟事件强制执行用户输入的效果,但我更喜欢覆盖输入流(在这种情况下为cin),以便程序对于强制决策的响应与用户自主决策无异。
我尝试像输出流一样将其写入(例如cin<<'z'
),但是<<运算符未定义为cin,我不知道如何定义它。
是否最好将其写入键盘缓冲区?如果是这样,如何以系统无关的方式进行操作?
写入输入是一种很巧妙的方法。更好的设计是在实际输入(如cin
)和处理该输入的游戏之间放置一个抽象层。然后,您可以仅在必要时重新配置此抽象层以响应程序生成的命令,而不是响应cin
。
std::cin
中,例如:class InjectedData : public std::streambuf
{
std::istream* myOwner;
std::streambuf* mySavedStreambuf;
std::string myData;
public:
InjectedData( std::istream& stream, std::string const& data )
: myOwner( &stream )
, mySavedStreambuf( stream.rdbuf() )
, myData( data )
{
setg( myData.data(), myData.data(), myData.data() + myData.size() );
}
~InjectedData()
{
myOwner->rdbuf(mySavedStreambuf);
}
int underflow() override
{
myOwner->rdbuf(mySavedStreambuf);
return mySavedStreambuf->sgetc();
}
};
std :: cin 作为参数构造此实例将返回 data 中的字符,直到该实例被销毁或所有字符都已被消耗。
InputSource
接口,一个实现为cin
,一个实现为“程序生成”,在必要时切换它们——对cin
进行抽象化处理。 - Angew is no longer proud of SOstd::istream
,那么它被称为装饰器(decorator)。(事实上,你想要装饰的是由std::cin
使用的streambuf。) - James Kanze