c只要写入流就执行函数
发布时间:2020-12-16 10:23:06 所属栏目:百科 来源:网络整理
导读:我有一个简单的GUI程序,它使用自定义字符串流将控制台的输出重定向到GUI中的文本字段(在某些情况下).目前.每当我按下Enter键时窗口都会重绘,但有时可能会在其他时间生成输出.有没有办法用每次操作符在流上使用? 注意 我应该指出我不能在我的解决方案中使用C
我有一个简单的GUI程序,它使用自定义字符串流将控制台的输出重定向到GUI中的文本字段(在某些情况下).目前.每当我按下Enter键时窗口都会重绘,但有时可能会在其他时间生成输出.有没有办法用每次<<<<<<<<<<<<<操作符在流上使用? 注意 我应该指出我不能在我的解决方案中使用C 11.将编译和运行它的机器将不具有c 11.
解决方法
就个人而言,我根本不会使用std :: ostringstream(甚至是std :: stringstream)!相反,我会创建自己的流缓冲区,负责将数据发送到GUI.也就是说,我会覆盖std :: streambuf :: overflow()和std :: streambuf :: sync()来将当前数据发送到GUI.为了确保立即发送任何输出,我设置了一个std :: ostream来设置std :: ios_base :: unitbuf.实际上,将更改发送到函数非常简单,即我将实现此:
#include <streambuf> #include <ostream> #include <functional> #include <string> #include <memory> #include <iostream> // only for testing... #if HAS_FUNCTION typedef std::function<void(std::string)> function_type; #else class function_type { private: struct base { virtual ~base() {} virtual base* clone() const = 0; virtual void call(std::string const&) = 0; }; template <typename Function> struct concrete : base { Function d_function; concrete(Function function) : d_function(function) { } base* clone() const { return new concrete<Function>(this->d_function); } void call(std::string const& value) { this->d_function(value); } }; std::auto_ptr<base> d_function; public: template <typename Function> function_type(Function function) : d_function(new concrete<Function>(function)) { } function_type(function_type const& other) : d_function(other.d_function->clone()) { } function_type& operator= (function_type other) { this->swap(other); return *this; } ~function_type() {} void swap(function_type& other) { std::swap(this->d_function,other.d_function); } void operator()(std::string const& value) { this->d_function->call(value); } }; #endif class functionbuf : public std::streambuf { private: typedef std::streambuf::traits_type traits_type; function_type d_function; char d_buffer[1024]; int overflow(int c) { if (!traits_type::eq_int_type(c,traits_type::eof())) { *this->pptr() = traits_type::to_char_type(c); this->pbump(1); } return this->sync()? traits_type::not_eof(c): traits_type::eof(); } int sync() { if (this->pbase() != this->pptr()) { this->d_function(std::string(this->pbase(),this->pptr())); this->setp(this->pbase(),this->epptr()); } return 0; } public: functionbuf(function_type const& function) : d_function(function) { this->setp(this->d_buffer,this->d_buffer + sizeof(this->d_buffer) - 1); } }; class ofunctionstream : private virtual functionbuf,public std::ostream { public: ofunctionstream(function_type const& function) : functionbuf(function),std::ostream(static_cast<std::streambuf*>(this)) { this->flags(std::ios_base::unitbuf); } }; void some_function(std::string const& value) { std::cout << "some_function(" << value << ")n"; } int main() { ofunctionstream out(&some_function); out << "hello" << ',' << " world: " << 42 << "n"; out << std::nounitbuf << "not" << " as " << "many" << " callsn" << std::flush; } 上面代码的一大部分实际上与手头的任务无关:它实现了std :: function< void(std :: string)>的原始版本.如果C 2011无法使用. 如果你不想要那么多的调用,你可以关闭std :: ios_base :: unitbuf并仅在刷新流时发送数据,例如使用std :: flush(是的,我知道std :: endl但不幸的是它通常被误用,我强烈建议摆脱它并使用std :: flush,其中一个flush是真的意思). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
热点阅读