重载操作符(2)


  支持I/O操作的类所提供的I/O操作接口,一般应该与标准库iostream为内置类型定义的接口相同。因此,许多类都需要重载输入和输出操作符。
  输出操作符<<的重载
  为了与IO标准库一致,操作符应接受ostream&作为第一个形参,对类类型const对象的引用作为第二个形参,并返回对ostream形参的引用。
  重载输出操作符一般的简单定义如下:
  // general skeleton of the overloaded ouput operator
  Ostream& operator <<(ostream& os, const ClassType &object)
  {
  // any special logic to prepare object
  
  // actual ouput of members
  os <   // return ostream object
  return os;
  }
  第一个形参是对ostream对象的引用,在该对象上产生输出,ostream为非const,因为下入到流会改变流的状态。该形参是一个引用,因为不能复制ostream对象。
  第二个对象一般应是对要输出的类类型的引用。该形参是一个引用以避免复制实参。它可以是const,因为输出一个对象不应该改变该对象。
  返回类型是一个ostream引用,它的值通常是输出操作符所操作的ostream对象。
  输出操作符通常所做格式化应尽量少。
  关于输出,类设计者面临着一个重要决定:是否格式化以及进行多少格式化。
  一般而言,输出操作符应输出对象的内容,进行最小限度的格式化,他们不应该输出换行符。
  用于内置类型的输出操作符所作的格式化很少,并且不输出换行符。通过限制输出操作符只输出对象的内容,如果需要执行任意额外的格式化,我们让用户决定该如何处理。尤其是,输出操作符不应该输出换行符。尽量减少操作符所作的格式化,让用户自己控制输出细节。
  IO操作符必须为非成员函数
  当定义符合标准库iostream规范的输入或输出操作符的时候,必须使它成为非成员操作符。

  我们不能将该操作符定义为类的成员,否则,左操作数将只能是该类类型的对象。
  // if operator <
  Sales_item item;
  item <
  这个用法与为其他类型定义的输出操作符的正常使用方式相反。如果想要支持正常的用法,则左操作数必须为ostream类型。如果该操作符是类的成员,则它必须是ostream类的成员,然而ostream类是标准库的组成部分,我们是不能为标准库的类增加成员的。
   如果想要使用重载操作符为该类型提供IO操作,就必须将他们定义为非成员函数。IO操作符通常对非公用数据成员进行读写,因此,类通常将IO操作符设为友元。
  
  输入操作符>>的重载
  与输出操作符类似:输入操作符的第一个形参是一个引用,指向它要读的流,并且返回的也是对同一个流的引用。它的第二个形参是对要读入的对象的非const引用,该形参必须为非const,因为输入操作符的目的是将数据读到这个对象中。
  ostream& operator >>(ostream& os, ClassType &object)
   需要注意的是:输入和输出操作符有如下区别,输入操作符必须处理错误和文件结束的可能性。
  如何处理输入错误
  如果输入操作符检测到输入失败了,则确保对象处于可用和一致的状态是个好做法。如果对象在错误发生之前已经写入了部分欣喜,这样做就特别重要。
  如果发生了错误,就将形参恢复为空对象,以避免给它一个无效的状态。用户如果需要知道输入是否成功,可以测试流。即使用户忽略了输入可能错误,对象仍处于可用状态——他的成员已经定义。
  设计输入操作符时,如果可能,要确定错误恢复措施,这很重要。
  指出错误
  除了处理可能发生的任何错误之外,输入操作符还可能需要设置输入形参的条件状态。我们的输入操作符相当简单——我们只关心读入期间可能发生的错误。
  
  算术操作符和关系操作符
   一般而言,将算术和关系操作符定义为非成员函数。为了与内置操作符保持一致,加法返回一个右值,而不是一个引用
  例:
  // assumes that both objects refer to the same isbn
  Sales_item operator +(const Sales_item& lhs, const Sales_item& rhs)
  {
  Sales_item ret(lhs);
  ret += rhs;
  return ret; // ret 因该理解为左值还是右值呢?概念有所混淆 我觉得返回的是左值
  }
  算术操作符通常产生一个新值,该值是两个操作数的计算结果,它不同于任一操作数且在一个局部变量中计算,返回对那个变量的引用是一个运行时的错误。
   既定义了算术操作符又定义了相关复合赋值操作符的类,一般应使用复合赋值实现算术操作符。
  
  赋值操作符
  类赋值操作符接受类类型的形参,通常,该形参是对类类型的const引用,但也可以是类类型或对类类型的非const 引用。如果没有定义这个操作符,编译器就会合成它。类赋值操作符必须是类的成员,以便编译器可以知道是否需要合成一个。
  赋值操作符可以重载。无论形参为何种类型, 赋值操作符必须定义为成员函数。
  赋值必须返回对*this的引用。
  因为赋值返回的是一个引用,就不需要创建和撤销结果的临时副本。返回值通常是左操作数的引用。

   注意:一般而言,赋值操作符与复合赋值操作符应返回左操作数的引用
  
  下标操作符
  下标操作符必须定义为类成员函数。
  提供读写访问
  定义下标操作符比较复杂的地方在于,它在用作赋值的左右操作数时都应该能表现正常,下标操作符出现在左边,必须生成左值,可以指定引用作为返回类型而得到左值。只要下标操作符返回引用,就可用作赋值的任意一方。
   类定义下标操作符的时候,一般需要定义两个版本:一个为非const成员并返回引用,另一个为const成员并返回const引用。
  
  自增操作符和自减操作符
  定义自增/自减操作符
  C++语言不要求自增操作符或自减操作符一定作为类的成员,但是,因为这些操作符改变操作对象的状态。但是,因为这些操作符改变操作对象的状态,所以更倾向于将他们作为成员函数。
  定义前自减/前自增操作符
  class CheckedPtr
  {
  public:
  CheckedPtr& operator++();
  CheckedPtr& operator—();
  };
  为了与内置类型一致,前缀式操作符应返回被增量或减量对象的引用。
  区别操作符的前缀和后缀形式
  前缀式和后缀式存在一个问题:它们的形参数目和类型相同
  为了解决这个问题,后缀式操作符函数接受一个额外的int型形参。使用后缀式操作符时,编译器提供0座位这个形参的实参。
  定义后缀式操作符
  class CheckedPtr
  {
  public:
  CheckedPtr operator ++ (int);
  CheckedPtr operator – (int);
  };
  为了与内置操作符一致,后缀式操作符应返回旧值(尚未自增或自减的值),并且应作为值返回,而不是返回应用。
  一般而言,最好前缀式和后缀式都定义。只定义前缀式或只定义后缀式的类,将会让习惯于使用两种形式的用户感到奇怪。
  
  调用操作符和函数对象
  可以为类类型的对象重载函数调用操作符。一般为表示操作的类重载调用操作符。
  例如,可以定义名为absInt的结构,该结构将int类型的值转换为绝对值得操作:
  class absInt
  {
  int operator()(int val)
  {
  Return val <0 ? –val: val;
  }
  };
  这个结构很简单,它定义了一个操作,函数调用操作符,该操作符有一个形参并返回形参的绝对值。
  通过类类型的对象提供一个实参表而使用调用操作符,所用的方式看起来像一个函数调用。
  函数调用操作符必须声明为成员函数,一个类可以定义函数调用操作符的多个版本,由形参的数目或类型加以区别。
  定义了调用操作符的类,其对象常称为函数对象,即它们是行为类似函数的对象。
  
  
  

本文转自
http://blog.youkuaiyun.com/sandyqy/archive/2007/10/07/1813649.aspx
内容概要:本文介绍了奕斯伟科技集团基于RISC-V架构开发的EAM2011芯片及其应用研究。EAM2011是一款高性能实时控制芯片,支持160MHz主频和AI算法,符合汽车电子AEC-Q100 Grade 2和ASIL-B安全标准。文章详细描述了芯片的关键特性、配套软件开发套件(SDK)和集成开发环境(IDE),以及基于该芯片的ESWINEBP3901开发板的硬件资源和接口配置。文中提供了详细的代码示例,涵盖时钟配置、GPIO控制、ADC采样、CAN通信、PWM输出及RTOS任务创建等功能实现。此外,还介绍了硬件申领流程、技术资料获取渠道及开发建议,帮助开发者高效启动基于EAM2011芯片的开发工作。 适合人群:具备嵌入式系统开发经验的研发人员,特别是对RISC-V架构感兴趣的工程师和技术爱好者。 使用场景及目标:①了解EAM2011芯片的特性和应用场景,如智能汽车、智能家居和工业控制;②掌握基于EAM2011芯片的开发板和芯片的硬件资源和接口配置;③学习如何实现基本的外设驱动,如GPIO、ADC、CAN、PWM等;④通过RTOS任务创建示例,理解多任务处理和实时系统的实现。 其他说明:开发者可以根据实际需求扩展这些基础功能。建议优先掌握《EAM2011参考手册》中的关键外设寄存器配置方法,这对底层驱动开发至关重要。同时,注意硬件申领的时效性和替代方案,确保开发工作的顺利进行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值