可重载的
输出操作符<< 的重载
为了与 IO 标准库一致,操作符应接受 ostream& 作为第一个形参,对类类型 const 对象的引用作为第二个形参,并返回对ostream 形参的引用。
重载输出操作符一般的简单定义如下:
// general skeleton of the overloaded output operator
ostream& operator <<(ostream& os, const ClassType &object)
{
// any special logic to prepare object
// actual output of members
os << // ...
// return ostream object
return os;
}
第一个形参是对 ostream 对象的引用,在该对象上将产生输出。ostream 为
非 const,因为写入到流会改变流的状态。该形参是一个引用,因为不能复制
ostream 对象。
第二个形参一般应是对要输出的类类型的引用。该形参是一个引用以避免复
制实参。它可以是 const,因为(一般而言)输出一个对象不应该改变对象。使
形参成为 const 引用,就可以使用同一个定义来输出 const 和非 const 对象。
返回类型是一个 ostream 引用,它的值通常是输出操作符所操作的
ostream 对象。
类通常将 IO 操作符设为友元。
如果作为成员函数(书上说不建议)
,左操作数将只能是该类类型的对象:
// if operator<< is a member of Sales_item
Sales_item item;
item << cout;
输入操纵符
istream&operator>>(istream& in, Sales_item& s)
{
in >> s.isbn >> s.units_sold >> price;
// check that the inputs succeeded
if (in)/////JIAN CHA
s.revenue = s.units_sold * price;
else
s = Sales_item(); // input failed: reset object to default
state
return in;
}
Sales_item operator+(const Sales_item& lhs, const Sales_item& rhs)
{
Sales_item ret(lhs); // copy lhs into a local object that we'll
return
ret += rhs; // add in the contents of rhs
return ret; // return ret by value
}
inline bool operator==(const Sales_item &lhs, const Sales_item &rhs)
{
// must be made a friend of Sales_item
return lhs.units_sold == rhs.units_sold &&
lhs.revenue == rhs.revenue &&
lhs.same_isbn(rhs);
}
inline bool operator!=(const Sales_item &lhs, const Sales_item &rhs)
{
return !(lhs == rhs); // != defined in terms of operator==
}
看看string 定义的=操作符 标准库
class string {
public:
string& operator=(const string &); // s1 = s2;
string& operator=(const char *); // s1 = "str";
string& operator=(char); // s1 = 'c';
// ....
};
string car ("Volks");
car = "Studebaker"; // string = const char*
string model;
model = 'T'; // string = char
赋值必须返回对 *this 的引用
Sales_item& Sales_item::operator+=(const Sales_item& rhs)
{
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
调用操作符
struct absInt {
int operator() (int val) {
return val < 0 ? -val : val;
}
通过为类类型的对象提供一个实参表而使用调用操作符,所用的方式看起来
像一个函数调用:
int i = -42;
absInt absObj; // object that defines function call operator
unsigned int ui = absObj(i); // calls absInt::operator(int)
尽管 absObj 是一个对象而不是函数,我们仍然可以“调用”该对象,效果
是运行由 absObj 对象定义的重载调用操作符,该操作符接受一个 int 并值并
返回它的绝对值。
转换操作符是一种特殊的类成员函数。它定义将类类型值转变为其他类型值
的转换。转换操作符在类定义体内声明,在保留字 operator 之后跟着转换的目
标类型:
class SmallInt {
public:
SmallInt(int i = 0): val(i)
{ if (i < 0 || i > 255)
throw std::out_of_range("Bad SmallInt initializer");
}
operator int() const { return val; }
private:
std::size_t val;
};
转换操作符 的使用
• 在表达式中:
SmallInt si;
double dval;
si >= dval // si converted to int and then convertto double
• 在条件中:
if (si) // si converted to int and then convertto bool
• 将实参传给函数或从函数返回值:
int calc(int);
SmallInt si;
int i = calc(si); // convert si to int and call calc
• 作为重载操作符的操作数:
// convert si to int then call opeator<< on the int value
cout << si << endl;
• 在显式类型转换中:
int ival;
SmallInt si = 3.541; //
instruct compiler to cast si to int
ival = static_cast<int>(si) + 3;