一、模拟 endl 输出换行并将缓冲区的数据刷新输出到屏幕显示
#include <iostream>
#define Stream std::basic_ostream<T1, T2>&
template<typename T1, typename T2>
Stream CRLF(Stream _out)
{
putchar('\n');
return _out.flush(); //清缓冲区
}
int main(void)
{
std::cout << "第一行" << CRLF; //已脱离std::空间
CRLF(std::cout); //还可以这样调用,单独输出一空行
std::cout << "第三行" << CRLF;
//std::cout << "第四行" << endl; //必须用std::endl
return 0;
}
/*
第一行
//第二行是空行
第三行
--------------------------------
Process exited after 1.197 seconds with return value 0
请按任意键继续. . .
*/
以下这样的代码更简洁:
#include <iostream>
std::ostream& endl (std::ostream& _os)
{
_os.put('\n');
_os.flush();
return _os;
}
int main(void)
{
std::cout << 1 << endl <<endl; //这是自定义的 endl
std::cout << 2 << std::endl; //这是std的 endl
endl(std::cout); //这是自定义的 endl
std::cout << "========" << endl;
std::endl(std::cout); //这是std的 endl
std::cout << "========" << std::endl;
return 0;
}
/*
1
2
========
========
--------------------------------
Process exited after 0.9518 seconds with return value 0
请按任意键继续. . .
*/
二、重载操作符 << 模拟输出语句: cout << 123 << "abc\n" << endl;
#include <iostream>
#include <string>
#include <typeinfo>
#define endl "\n"
class myOutText{
public:
myOutText &operator << (auto s) {
std::string str;
if (typeid(s).name()==typeid(std::string("")).name()) str=s;
if (str==endl) {
std::cout << endl;
std::cout.flush();
}
else
std::cout << s ;
//return *this; //返回自身引用以支持连续操作
}
};
int main(void)
{
myOutText cout;
auto a = "abc";
double b = 8.9;
cout << "string1-" << a;
cout << endl;
cout << "1<<23<<4.56:" << endl;
cout << 1 << 23 << 4.56e-7 << " "
<< b << endl << "crlf" << endl;
std::string str = "endl";
cout << str << endl << endl;
return 0;
}
/*
string1-abc
1<<23<<4.56:
1234.56e-007 8.9
crlf
endl
--------------------------------
Process exited after 1.198 seconds with return value 0
请按任意键继续. . .
*/
关于<<重载后连续使用的问题还上思否去请教过,感谢TianSong小哥的指点:使用 return *this 返回自身引用。在此放出经他修改过的代码:
#include <iostream>
class myOutText{
public:
myOutText &operator << (auto s) {
std::cout << s;
return *this;
}
myOutText &operator << (void(*obj)(myOutText&)) {
obj(*this);
return *this;
}
void flush() {
std::cout.flush();
}
};
void endl(myOutText &obj)
{
obj << '\n';
obj.flush();
}
int main(void)
{
myOutText cout;
std::string str="abcd";
cout << "string<<" << str << endl;
cout << "1<<2<<" << endl <<endl;
cout << 1 << 2.3 << str << endl;
return 0;
}
/*
string<<abcd
1<<2<<
12.3abcd
--------------------------------
Process exited after 0.4635 seconds with return value 0
请按任意键继续. . .
*/
TianSong的赠言和遵循的原则,也值得学习:
梅耶(Scott Meyers) 的经典名言 “恭喜大家,坐上了通往未定义道路的宇宙飞船”。
我遵循的两条原则:
- 编译器警告即错误(除非十分清楚);
- 违背基础语法、理论的事不做。
附:
例程二用到了操作符 typeid ,详细用法请见: 《用 typeid 操作符 做一个C++数据类型大全》