重学C++ (九) 重载操作符与转换
来源:互联网 发布:为什么开不了淘宝店铺 编辑:程序博客网 时间:2024/05/01 18:58
1.重载操作符必须具有至少一个类类型或枚举类型的操作数(内置类型的操作符含义不能改变);
2.除了函数调用操作符operator()之外,重载操作符时不能使用默认实参;
3.重载之后&&, ||不再具备短路求值特征;
4.作为成员函数的操作符有一个隐含的this形参,限定为第一个操作数;
一般将算数和关系操作符定义为非成员函数,而将赋值操作符定义为成员:
//成员函数Sales_item& Sales_item::operator += (const Sales_item&);//非成员函数Sales_item operator + (const Sales_item&, const Sales_item&);
5.操作符定义为非成员函数时,通常需要将它们设置为所操作类的友元(这样才能访问私有数据成员);
6.赋值(=)、下标([ ])、调用(( ))、和成员访问箭头(->)必须定义为成员函数;
IO操作符必须为非成员函数,类通常将IO操作符设为友元;
7.输入输出操作符重载(必须为非成员函数)
//输出操作符,返回流的引用。//输出不修改值,所以第二个参数为const引用ostream& operator << (ostream & out, const ClassType & obj){ //doSomething out<< // ... return out;}//输入操作符,返回流的引用。//输入修改值,所以第二个参数为非const引用istream& operator >> (istream & in, ClassType & obj){ //doSomething in>> // ... //注意需要处理输入错误以及文件结束等情况! return in;}//例子:istream& operator >> (istream & in, Sales_item & s){ double price; in >> s.isbn >> s.units_sold >> price; //检测是否输入成功 if (in) s.revenue = s.units_sold * price; else s = Sales_item(); //输入失败,reset to default state return in;}
8.算术操作符和关系操作符
// assumes that both objects refer to the same book//加法返回的是一个右值,而不是引用Sales_dataoperator + (const Sales_data &lhs, const Sales_data &rhs){ Sales_data sum = lhs; // copy data members from lhs into sum sum += rhs; // add rhs into sum,前提是定义了+=操作符 return sum;}bool operator == (const Sales_data &lhs, const Sales_data &rhs){ return lhs.isbn() == rhs.isbn() && lhs.units_sold == rhs.units_sold && lhs.revenue == rhs.revenue;}bool operator != (const Sales_data &lhs, const Sales_data &rhs){ return !(lhs == rhs); //通过 == 操作符来定义!=}
9.赋值操作符
// = 操作符StrVec& StrVec::operator=(initializer_list<string> il){ // alloc_n_copy allocates space and copies elements from the given range auto data = alloc_n_copy(il.begin(), il.end()); free(); // destroy the elements in this object and free the space elements = data.first; // update data members to point to the new space first_free = cap = data.second; return *this;}// += 操作符// member binary operator: left-hand operand is bound to the implicit this pointer// assumes that both objects refer to the same bookSales_data& Sales_data::operator+=(const Sales_data &rhs){ units_sold += rhs.units_sold; revenue += rhs.revenue; return *this;}
10.下标操作符*
//类定义下标操作符时,一般需要定义两个版本://非const成员并返回引用;//const成员并返回const引用;class StrVec {public: std::string& operator [] (std::size_t n) { return elements[n]; } const std::string& operator [] (std::size_t n) const { return elements[n]; }private: std::string *elements; // pointer to the first element in the array};
11.自增、自减操作符
//前缀自增自减,返回自身的引用class StrBlobPtr {public: // increment and decrement StrBlobPtr& operator++(); // prefix operators StrBlobPtr& operator--(); // other members as before};// prefix: return a reference to the incremented/decremented objectStrBlobPtr& StrBlobPtr::operator++(){ // if curr already points past the end of the container, can't increment it check(curr, "increment past end of StrBlobPtr"); ++curr; // advance the current state return *this;}StrBlobPtr& StrBlobPtr::operator--(){ // if curr is zero, decrementing it will yield an invalid subscript --curr; // move the current state back one element check(-1, "decrement past begin of StrBlobPtr"); return *this;}//后缀自增自减,先保存原值,自增后返回自增前的值,故不用引用;//为区别前缀和后缀,后缀操作符函数接收一个无用的int型形参;//在后缀操作符中,可以使用前缀操作符来实现自增自减;class StrBlobPtr {public: // increment and decrement StrBlobPtr operator++(int); // postfix operators StrBlobPtr operator--(int); // other members as before};// postfix: increment/decrement the object but return the unchanged valueStrBlobPtr StrBlobPtr::operator++(int){ // no check needed here; the call to prefix increment will do the check StrBlobPtr ret = *this; // save the current value ++*this; // advance one element; prefix ++ checks the increment return ret; // return the saved state}StrBlobPtr StrBlobPtr::operator--(int){ // no check needed here; the call to prefix decrement will do the check StrBlobPtr ret = *this; // save the current value --*this; // move backward one element; prefix -- checks thedecrement return ret; // return the saved state}
12.调用操作符和函数对象
struct absInt { int operator()(int val) const { return val < 0 ? -val : val; }};//定义了调用操作符的类,其对象称为函数对象;int i = -42;absInt absObj; // object that has a function-call operatorint ui = absObj(i); // passes i to absObj.operator()
**标准库定义了一些函数对象,在functional头文件中定义;
13.转换与类类型
class SmallInt {public: SmallInt(int i = 0): val(i) { if (i < 0 || i > 255) throw std::out_of_range("Bad SmallInt value"); } //转换操作符,必须是成员函数,不能指定返回类型,形参表必须为空 //一般不应改变被转换的对象,所以为const; operator int() const { return val; }private: std::size_t val;};//使用Smallint si;double dval;if (si >= dval) //si转换为int,之后再转换为double //...cout << si <<endl; //si转换为int之后调用<<操作符
注意,只允许一次类类型转换:
比如可以Integral->SmallInt->int;但不能Integral->int;
14.给定以下代码:
ClassX sc;int iobj = sc + 3;
有四种可能:
1.有一个重载加操作符与ClassX和int相匹配;
2.存在转换,则先进行类型转换,再进行加操作;
3.既定义了转换操作符又定义了+的重载版本,该表达式具有二义性;
4.既没有转换又没有重载+,该表达式非法。
0 0
- 重学C++ (九) 重载操作符与转换
- c++学习札记(九)---重载操作符与转换
- 《C++Primer》3.15重载操作符与转换
- 《c++primer》读书笔记三 重载操作符与转换
- c++Primer,十四,重载操作符与转换
- 重载操作符与转换
- 重载操作符与转换
- 重载操作符与转换
- 重载操作符与转换
- 类型转换和操作符重载 (c#)
- 重载操作符与转换(1)
- 第十四章:重载操作符与转换
- 第十四章 重载操作符与转换
- C++ primer:重载操作符与转换
- Chapter 24.重载操作符与转换
- 第十四章 重载操作符与转换
- [C++ Primer] 重载操作符与转换
- C++ 重载操作符与转换
- 80x86 汇编语言:在屏幕右上角显示系统时间
- 云存储平台之运营
- 汇编语言编程:1 + 2 + 3 + 4 + 5 + …… + n
- matlab---画图
- 汇编编程问题:X + Y + Z => 显示
- 重学C++ (九) 重载操作符与转换
- 晒晒新买的“百度旋转音箱”
- 比较两个无符号数的大小
- jQuery/Json/Ajax基础知识
- 驱动大尺寸数码管的方法与电路
- linux下清除svn账号和密码
- P1 接 8 个独立按键,P2 接 8 个 LED,要求用按键控制 LED 的发光状态
- 设计一个显示ASCII码的程序
- 统计一个字符串中某个字母的个数