在用C++编写程序时,最常用的就是变量的输入输出了。在C++中,一般用cin和cout来实现变量的输入和输出。但是,cin和cout并不是C++内部定义的运算符,而分别是istream类和ostream类的对象。而且都位于std命名空间中。
在类中实现cin和cout操作时,用到了运算符“<<”的重载。
那么由此以来我们自己也可以通过重载“<<”和“>>”来实现输入输出操作。
定义MyOut类,在类中通过重载“<<”运算符实现整型变量和字符型变量的输出,并且不利用std命名空间。
#include<iostream> //使用c++非标准库,里面包含printf
class MyOut{
public:
MyOut(){}; //构造函数
~MyOut(){}; //析构函数
const void &operator<<(int value)const; //输出整型变量
const void &operator<<(char c)const; //输出字符型变量
}
//输出整型变量
const void &MyOut::operator<<(int value)const
{
printf("%d",value);
}
//输出字符型变量
const void &MyOut::operator<<(char c)const
{
printf("%c",c);
}
int main()
{
int n=5; //声明整型变量n=5
MyOut myout; //MyOut类的对象myout,可类比ostream类的cout对象
myout<<n; //输出n
myout<<'\n'; //输出换行符
}
通过运行上述程序,能够得到我们期望的结果。但是,不能够连续的输出,只能一次输出一个变量。
1、实现连续输出
然而,cout是能够连续输出的,它是怎么做到的呢?
我们知道,对于每一个类的成员函数(静态成员函数除外),都有一个指向当前对象的*this指针。若将运算符重载函数声明为MyOut类型,在函数中返回当前对象的this指针后,下一次在调用函数时,是在之前的基础上调用的,即实现了对对象的连续操作。
修改后,类的实现如下:
class MyOut{
public:
MyOut(){}; //构造函数
~MyOut(){}; //析构函数
const MyOut &operator<<(int value)const; //输出整型变量
const MyOut &operator<<(char c)const; //输出字符型变量
}
//输出整型变量
const MyOut &MyOut::operator<<(int value)const
{
printf("%d",value);
return *this;
}
//输出字符型变量
const MyOut &MyOut::operator<<(char c)const
{
printf("%c",c);
return *this;
}
经过以上操作,可以实现基本的输出操作。当然,可以向MyOut类中添加其他的成员函数,实现更多的输出功能。比如,cout的输出宽度设定,输出数据的进制设置等等。而cin的操作与其类似。
2、endl和’\n’的区别
在C++标准库中,是利用“endl”来实现换行的,而我们自己实现时,是直接输出了换行符’\n’。那么,两者究竟有什么区别呢?
1. 首先,endl是一种定义在iostream文件中的IO操作符。
2. 在ostream类中,重载操作符<<时,有如下定义:
ostream& ostream::operator << ( ostream& (*op) (ostream&))
{
// call the function passed as parameter with this stream as the argument
return (*op) (*this);
}
而对于endl函数的实现如下:
std::ostream& std::endl (std::ostream& strm)
{
// write newline
strm.put('\n');
// flush the output buffer
strm.flush();
// return strm to allow chaining
return strm;
}
由上述可知,endl作为函数名,经函数指针传递给重载<<函数中的*op,从而实现对endl()函数的调用。
3. 它的作用是插入换行符并强制刷新输出缓冲区,将输出缓冲区中的数据写入文件或屏幕。
而换行符’\n’或“\n”并没有刷新缓冲区的功能。
当遇到大程序时,用“\n”换行,能够提高运行效率。