关于ostream类的满载函数
关于ostream类的重载函数
#include <iostream>
//声明类Point
class Point
{public:
Point(float x=0,float y=0);//有默认参数的构造函数
void setPoint(float,float); // 设置坐标值
float getX( ) const {return x;} // 读x坐标
float getY( ) const {return y;} // 读y坐标
friend ostream& operator<<(ostream&,const Point &);//重载运算符“<<”
protected: // 受保护成员
float x,y;
};
//下面定义Point类的成员函数
//Point的构造函数
Point::Point(float a,float b) // 对x,y初始化
{x=a;y=b;}
//设置x和y的坐标值
void Point::setPoint(float a,float b) // 为x,y赋新值
{x=a;y=b;}
//重载运算符“<<”,使之能输出点的坐标
ostream& operator<<(ostream&output,const Point &p)
{output<<″[″<<p.x<<″,″<<p.y<<″]″<<endl;
return output;
}
能帮我解释下这个"<<"的重载函数吗,为什么函数有两个参数,返回值是ostream的引用?
------解决方案--------------------
效率问题!流对象也是很复杂的!所以尽量减少不必要的中间临时的拷贝操作!
可以提高执行速度
------解决方案--------------------
不需要想得太复杂,你先理解下一般的操作符重载。有这几种情况,成员或者友元(或者是一般的全局函数同友元),然后又分为一目操作符重载和双目运算符重载。
先说下双目运算符,成员的情况下是单参数的,调用对象是该类型本身,参数是传递的对象。比如a+b等价于a.operator+(b)。如果是友元,前者是调用参数是第一参数,后者是传递对象,第二参数。a+b就等价于operator+(a,b);
你的例子中operator<<(ostream&output,const Point &p),前面那个就是第一参数,后面那个就是第二参数了。比如这样写,cout<<p;等价于operator<<(cout,p)。
如果是成员的写法可以这样,不过要反过来,因为你的调用对象是Point,operator<<(ostream&output),那么调用的时候就要这样p<<cout,等价于p.operator<<(cout);不过这个对操作流比较特殊
再说下单目的情况,单目的话比如正负号 + -,等等,这个只有一个参数,而且都是前置的。比如Point operator+(){},那么使用的时候就是+p,等价的就是p.operator+();
这里有个特殊情况,就是++,--他们有2种写法,就是++p和p++,如果你根据上面的参数来定义,调用的一定是前缀的++,就是++p,而不是p++。声明的时候要这样Point operator++(int){},这里有个int,不过这个并非是双目运算符的意思,只是一个后缀标志,表示你调用的是后缀形式。你完全不需要给这个参数名称,也不会在下面用到他。
该说的基本都说了,至于返回什么都是自己定义的,你可能完全不返回也可以,比如声明为void。或者返回对象本身也可以,不需要返回引用。不过这里返回引用无非是2个原因:
#include <iostream>
//声明类Point
class Point
{public:
Point(float x=0,float y=0);//有默认参数的构造函数
void setPoint(float,float); // 设置坐标值
float getX( ) const {return x;} // 读x坐标
float getY( ) const {return y;} // 读y坐标
friend ostream& operator<<(ostream&,const Point &);//重载运算符“<<”
protected: // 受保护成员
float x,y;
};
//下面定义Point类的成员函数
//Point的构造函数
Point::Point(float a,float b) // 对x,y初始化
{x=a;y=b;}
//设置x和y的坐标值
void Point::setPoint(float a,float b) // 为x,y赋新值
{x=a;y=b;}
//重载运算符“<<”,使之能输出点的坐标
ostream& operator<<(ostream&output,const Point &p)
{output<<″[″<<p.x<<″,″<<p.y<<″]″<<endl;
return output;
}
能帮我解释下这个"<<"的重载函数吗,为什么函数有两个参数,返回值是ostream的引用?
------解决方案--------------------
效率问题!流对象也是很复杂的!所以尽量减少不必要的中间临时的拷贝操作!
可以提高执行速度
------解决方案--------------------
不需要想得太复杂,你先理解下一般的操作符重载。有这几种情况,成员或者友元(或者是一般的全局函数同友元),然后又分为一目操作符重载和双目运算符重载。
先说下双目运算符,成员的情况下是单参数的,调用对象是该类型本身,参数是传递的对象。比如a+b等价于a.operator+(b)。如果是友元,前者是调用参数是第一参数,后者是传递对象,第二参数。a+b就等价于operator+(a,b);
你的例子中operator<<(ostream&output,const Point &p),前面那个就是第一参数,后面那个就是第二参数了。比如这样写,cout<<p;等价于operator<<(cout,p)。
如果是成员的写法可以这样,不过要反过来,因为你的调用对象是Point,operator<<(ostream&output),那么调用的时候就要这样p<<cout,等价于p.operator<<(cout);不过这个对操作流比较特殊
再说下单目的情况,单目的话比如正负号 + -,等等,这个只有一个参数,而且都是前置的。比如Point operator+(){},那么使用的时候就是+p,等价的就是p.operator+();
这里有个特殊情况,就是++,--他们有2种写法,就是++p和p++,如果你根据上面的参数来定义,调用的一定是前缀的++,就是++p,而不是p++。声明的时候要这样Point operator++(int){},这里有个int,不过这个并非是双目运算符的意思,只是一个后缀标志,表示你调用的是后缀形式。你完全不需要给这个参数名称,也不会在下面用到他。
该说的基本都说了,至于返回什么都是自己定义的,你可能完全不返回也可以,比如声明为void。或者返回对象本身也可以,不需要返回引用。不过这里返回引用无非是2个原因:
1、流对象比较复杂,用引用可以节省时间
2、可以用这种形式,连续的使用输出流:cout<<a<<b<<c;
cout<<a,返回了一个输出流引用,然后把该引用对象作为新的输出流给b使用,out<<b