定义用于读取和写入的运算符[] [英] defining operator [ ] for both reading and writing

查看:244
本文介绍了定义用于读取和写入的运算符[]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C ++编程语言这本书中,作者给出了以下示例以及一些语句:

In the book of "The C++ Programming Language", the author gave the following example along with several statements:


定义一个运算符,例如[]用于读取和写入非常困难,因为仅仅返回一个引用并让用户决定如何使用它是不可接受的。

Defining an operator, such as [], to be used for both reading and writing is difficult where it is not acceptable simply to return a reference and let the user decide what to do with it.

Cref,可以帮助您实现一个区分读写的下标运算符。

Cref, is to help implement a subscript operator that distinguishes between reading and writing.

为什么在同时用于读写时很难定义[]?
Cref类的定义如何解决该问题?

Why [] is difficult to be defined when to be used for both reading and writing? How does the definition of class Cref help to solve this issue?

  class String{
     struct Srep; 
     Srep *rep; 

     public: 
        class Cref;
        
     // some definitions here
     void check (int i) const { if (i<0 || rep->sz<=i) throw Range( );}
     
     char read( int i) const {return rep->s[i];}
     void write(int i, char c){ rep=rep->get_own_copy(); rep->s[i]=c;}

     Cref operator[] (int i){ check(i); return Cref(*this, i);}
     char operator[] (int i) const{check(i); return rep->s{i];}

   }

  class String::Cref{
    friend class String;
          String& s;
          int i;
          Cref(String& ss, int ii): s(ss),i(ii) {}
    public:
          operator char( ) { return s.read(i);}
          void operator=(char c){s.write(i,c);}
  };


推荐答案

如果您未定义类 Cref 解决了此问题,然后您必须执行 std :: map 要做的事情:

If you don't define a class Cref that solves this issue, then you have to do what std::map does:

template class <K,V> class map{
   V& operator[](K const & key);
}

这将返回引用,必须支持

This returns a reference, which must be backed by a valid memory location, and therefore

std::map<string,string> m;
m["foo"];
assert(m.find("foo") != m.end());

断言将成功(这意味着 foo 现在是地图中的有效键),即使您从未分配任何内容给 m [ foo]

The assertion will succeed (meaning, "foo" is now a valid key in the map) even though you never assigned something to m["foo"].

示例中的 Cref 类可以解决此违反直觉的行为-它可以执行适当的逻辑来创建 m [ foo ] 仅当您分配给引用时,并确保 m.find( foo)== m.end()当您尝试读取不存在的 m [ foo] 时,请不要执行某些作业。

This counterintuitive behavior can be fixed by the Cref class in your example -- it can perform the appropriate logic to create m["foo"] only when you assign to the reference, and ensure that m.find("foo") == m.end() if you didn't perform some assignment when you tried to read the nonexistant m["foo"].

您的 String 类(这是一个引用计数的字符串-字符串共享其字符串数据,并且当您更改一个与其他字符串共享数据的字符串时,将创建一个新副本) ),则在使用 operator [] 读取字符时必须进行复制。使用 Cref 类,可以确保仅在使用 operator [] 编写时才进行复制

Likewise, in your String class (which is a reference-counted string -- strings share their string data, and a new copy is created when you change a string whose data is shared with another string), you'd have to make a copy when using operator[] to read characters. The use of the Cref class, allows you to ensure that you only make a copy when using operator[] to write.

这篇关于定义用于读取和写入的运算符[]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆