重载运算符与类型转换(二)(学习笔记)

参考书籍:primer C++

5.下标运算符

表示容器的类通常可以通过元素在容器中的位置访问元素,这些类一般会定义下标运算符operator[];
下标运算符必须是成员函数。下标运算符通常以所访问元素的引用作为返回值,这样做的好处是下标可以出现在赋值运算符的任意一端。如果一个类包含下标运算符,则它通常会定义两个版本,一个返回普通引用,一个是类的常量成员且返回常量引用。

例:

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;  //指向数组首元素的指针
          };

//假设svec是一个StrVec的对象
const StrVec cvec = svec;     //把svec的元素拷贝到cvec中
//如果svec中含有元素,对第一个元素进行string的empty函数
if (svec.size() && svec[0].empty))
{
    svec[0] = "zero";  //正确:下标运算符返回string的引用
    cvec[0] = "Zip";  //错误:对cvec取下标返回的是常量引用
}

6.递增和递减运算符

定义递增和递减运算符的类应该同时定义前置版本和后置版本,这些运算符通常应该被定义为类的成员。

定义前置递增/递减运算符
在StrBlobPtr类中定义它们:

class StrBlobPtr{
public:
           //递增和递减运算符
           StrBlobPtr& operator++();
           StrBlobPtr& operator--();
           };

其工作机理为:首先调用check函数检验当前类是否有效,如果是,接着检查给定的索引值是否有效。如果check函数没有抛出异常,则运算符返回对象的引用。

// 前置版本:返回递增/递减对象的引用
StrBlobPtr& StrBlobPtr::operator++()
{
    //如果curr已经指向了容器的尾后位置,则无法递增它
    check (curr,"increment  past end of StrBlobPtr");
    ++curr;  //将curr在当前状态下向前移动一个元素
    return *this;   //返回递增后对象的引用
} 

递减同理。

区分前置和后置运算符
后置版本接受一个额外的(不被使用的)int类型的形参,且后置运算符返回对象的原值(递增/递减之前的值),返回的形式是一个值而非一个引用。
同样在StrBlobPtr中添加后置运算符:

class StrBlobPtr {
  public:
  StrBlobPtr operator++(int);
  StrBlobPtr operator--(int);
  };

StrBlobPtr StrBlobPtr::operator++(int)
{
  //此处无须检查有效性,调用前置递增运算时才需要检查
  StrBlobPtr ret = *this;   //记录当前值
  ++*this;                          //向前移动一个元素,前置++需要检查递增的有效性
  return ret;                      //返回之前记录的状态
}

StrBlobPtr StrBlobPtr::operator--(int)
{
  //此处无须检查有效性,调用前置递减运算时才需要检查
  StrBlobPtr ret = *this;   //记录当前值
  --*this;                          //向后移动一个元素,前置--需要检查递减的有效性
  return ret;                      //返回之前记录的状态
}

7.成员访问运算符

箭头运算符必须是类的成员函数,解引用运算符一般来说也是,但不

class  StrBlobPtr {
public:
          std::string& operator*() const
          {
          auto p = check(curr, "dereference past end");
          return (*p) [curr];      //(*p)是对象所指的vector
          }
          std::string* operator->() const
          {
             //将实际工作委托给解引用运算符
             return & this->operator* ();
             }
          }

 运算符的用法与指针或者vector迭代器的对应操作完全一致:

StrBlob a1 = {“hi”,”bye”,”now”};
StrBlobPtr p(a1); //p指向a1中的vector
*p = “okay”; //将a1的首元素赋值
cout << p->size() <

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值