C++Prime14章学习笔记

14. 重载运算与类型转换

14.1基本概念

重载的运算符是具有特殊名字的函数,它由关键字 operator与后面定义的符号组成,重载函数包含返回类型,参数列表以及函数体。重载运算符的参数数量与该运算符的作用的运算对象数量一样多。
如果一个运算符函数是成员函数,则其第一个运算对象绑定到this指针上。

注意:

  1. 对于一个运算符函数来说,它或者是类的成员或者至少含有一个类类型的参数。
  2. 同时只能重载已有的运算符,而不能发明新的符号。
  3. 对于一个重载的运算符来说,其优先级与结合律与对应的内置运算符保持一致

直接调用一个重载运算符
通常情况下,我们将运算符作用于类型正确的实参,从而以这种间接方式调用重载的运算符函数。然而,我们也能像普通函数一样调用运算符函数,然后传入数量正确类型恰当的实参

data1+data2; //普通的表达式
operator+(data1,data2);

这两次调用是等价的,他们都调用了非成员函数operator+,传入data1为第一个实参,传入 data2为第二个实参。

接下来像调用其他成员一样显示的调用成员运算符,具体做法是,首先制定运行函数对象和指针的名字,然后使用运算符访问希望调用的函数。

data1 += data2;   //基于调用的表达式
data1.operator+=(data2); //对成员运算符函数的等价调用

某些运算符不应该被重载
通常情况下不应该重载逗号,取地址,逻辑与和逻辑或运算符。

赋值和复合运算符
赋值运算符的行为与复合版本的类似:赋值之后,左侧运算对象和右侧运算对象的值相等,并且运算符应返回左侧对象的一个引用。重载的赋值应该继承非违背其内置版本的含义。

选择作为成员还是非成员
准则:

  1. 赋值(=),下标([ ]),调用(())和成员访问箭头(->)运算符必须是成员。
  2. 复合赋值运算符一般来说是成员,但并非必须。
  3. 改变运算状态的运算符或者给定类型密切相关的运算符,如递增,递减和解引用运算符,通常应该是成员、
  4. 具有对称性的运算符可以转换为任意运算对象,如算术,相等性,关系,位运算符等,因此它应该包含普通的非成员函数

14.2 输入和输出运算符

14.2.1重载输出运算符<<

Tips:通常输出运算符应该主要负责打印对象的内容而非控制格式,输出运算符不应当打印换行运算符。

输入输出运算符必须是非成员函数。

14.2.2重载输入运算符

输入时执行错误,和标识错误
标识错误:输入运算符可能检测bookNo是否符合格式,

14.3算术和关系运算符

14.3.1相等运算符

注意事项:相等运算符和不等运算符应该同时定义。

14.4赋值运算符

一个赋值运算符的例子

StrVec &StrVec::oprerator=(initializer_list<string> il){
   //alloc_n_copy分配内存空间
   auto data = alloc_n_copy(il.begin(), il.end());
   free();
   element = data.first;
   first_free = cap = data.second;
   return *this

14.5 下标运算符

一般定义为operator[]
一般需要定义下标运算符的常量和非常量版本,同时,已所访问元素的引用作为返回值。
例如

class StrVec{
 public:
    string& operator[](size_t n){
     return elements[n];}
   const string& operator[](size_t n) const {
     return elements[n];}
  private:
    string *elements;

14.6递增和递减运算符

区分前置和后置运算符,后置版本接受一个额外的(int)形参
对于后置版本来说,在递增对象之前需要记录对象的状态。

14.7 成员访问运算符

14.8 函数调用运算符

如果重载了函数调用运算符,也可以像使用函数一样使用该类的对象。因为这样的类同时也能储存状态。

struct absInt{
   int operator() (int val) const{
      return val<0? -val: +val;
      };

这个类只定义了一种操作,函数调用运算符,它接受一个Int类型的实参,然后返回实参的绝对值。
令一个absInt对象作用于一个实参列表

int  i = - 42;
absInt absObj;
int ui = absObj(i);

如果定义了调用运算符,则该类的对象称为函数对象。

14.8.1 lamba为函数对象
14.8.2 标准库定义的函数对象
14.8.3可调用对象与function

由于存在几个调用对象共享同一种调用形式的现象。因此,需要定义一个函数表用于储存这些可调用对象的指针。这时候需要调用function的标准库来解决问题。

function是一个模板,在创建具体类型时必须提供额外的信息

function<int(int,int)>

对于不同类型有

function<int(int,int)>f1 = add //函数指针
function<int(int,int)>f2 = divide //函数对象类的对象
function<int(int,int)>f3 = [](int i, int j){return i*j};
//lambda

14.9 重载,类型转换与运算符

14.9.1类类型转换

类型转换运算符是类的一种特殊成员函数,它负责将一个类型的值转换为其他类型,一般如下

operator type() const

其中type表示某种类型。类型运算符可以面向任意类型进行定义。(除了void)因此,不允许转换为数组或函数类型。但允许转换为指针类型或引用类型。

定义含有类型转换的运算符

class SmallInt{
   public:
      SmallInt(int i = 0): val(i)
      {
         if(i<0||i>255)
            throw std::out_of_range("Bad SmallInt Value");
       }
      operator int() const{ return val; }
   private:
      std::size_t val;};

Small int 定义了向类类型的转换和从类类型像其它类型的转换。其中,构造函数将算术运算符的值转换为SmallInt对象。

SmallInt si;
si = 4; //首先将4隐式的转换为smallInt,然后调用operator=函数
si + 3;  //将si转换为隐式的int再调用加法。

由于类型转换运算符是隐式执行的。因此无法传递实参,也不能使用任何形参。同时,每个类型转换函数返回一个对应类型的值。

class SmallInt;
operator int(SmallInt&) //错误:不是成员函数
class SmallInt{
   public:
     int operator int() const; //错误,指定返回类型
     operator int(int = 0) const; //错误,参数列表不为空
     operator int*() const{ return 42; }

由于类型转换运算符可能产生意外,为了防止这种意外发生,往往采用显示运算符。

class SmallInt{
   public:
   //编译器不会自动执行这一类型的转换
   explict operator int() const{ return val} 
};

此时只能显示的进行类型转换

static_cast<int>si + 3;

当然,这些规定存在着一个例外。当表达式出现在下列位置时转换将隐式的执行。

  1. if,while与do语序的条件部分
  2. for语句的条件表达式
  3. 逻辑非,与,或运算符的运算对象
  4. 条件运算符的条件表达式

转换为bool
无论在什么时候在条件中使用流对象,都会使用I/O类型的operator bool

while(cin>>value);

while语句输入条件执行运算符,它负责将输入读到value并返回cin,为条件求值,cin被istream operator bool进行了隐式转换,真返回true;

14.9.2 避免二义性类型转换

如果一个类中包含一个或多个类型转换。则必须保证类类型和目标类型之间只有一种转换方式。
在两种情况下会产生二义性。第一种情况是两个类提供相同的类型转换。第二种情况是定义了多个转换规则,而这些规则可以通过其他规则联系在一起。

要正确的设计类的重载运算符,转换构造函数及类型转换函数。
(1)不要令两个类执行相同的类型转换,如果Foo类有一个接受Bar类对象的构造函数,则不要在Bar类中定义Foo的转换构造符。
(2)避免转换的目标是内置算术类型的类型转换,特别是定义了一个转换成算术类型的类型转换时。不要再定义接受算术类型的重载运算符。如果用户需要使用这样的运算符,则类型转换操作将转换你类型的对象,然后使用内置的运算符。不要定义转换到多种类型的算术转换。

重载函数与用户定义的类型转换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值