设为首页 加入收藏

TOP

Item 3: Use const whenever possible.(8)
2013-10-07 14:26:22 来源: 作者: 【 】 浏览:58
Tags:Item Use const whenever possible.

What you really want to do is implement operator[] functionality once and use it twice. That is, you want to have one version of operator[] call the other one. And that brings us to casting away constness.

As a general rule, casting is such a bad idea, I’ve devoted an entire Item to telling you not to do it (Item 27), but code duplication is no picnic, either. In this case, the const version of operator[] does exactly what the non-const version does, it just has a const-qualified return type. Casting away the const on the return value is safe, in this case, because whoever called the non-const operator[] must have had a non-const object in the first place. Otherwise they couldn’t have called a non-const function. So having the non-const operator[] call the const version is a safe way to avoid code duplication, even though it requires a cast. Here’s the code, but it may be clearer after you read the explanation that follows:

  1. class TextBlock {  
  2. public:  
  3.   ...  
  4.   const char& operator[](std::size_t position) const  // same as before  
  5.   {  
  6.     ...  
  7.     ...  
  8.     ...  
  9.     return text[position];  
  10.   }  
  11.   char& operator[](std::size_t position)  // now just calls const op[]  
  12.   {  
  13.     return 
  14.       const_cast<char&>(  // cast away const on  
  15.  // op[]’s return type;  
  16.         static_cast<const TextBlock&>(*this)  // add const to *this’s type;  
  17.           [position]  // call const version of op[]  
  18.       );  
  19.   }  
  20. ...  
  21. }; 

As you can see, the code has two casts, not one. We want the non-const operator[] to call the const one, but if, inside the non-const operator[], we just call operator[], we’ll recursively call ourselves. That’s only entertaining the first million or so times. To avoid infinite recursion, we have to specify that we want to call the const operator[], but there’s no direct way to do that. Instead, we cast *this from its native type of TextBlock& to const TextBlock&. Yes, we use a cast to add const! So we have two casts: one to add const to *this (so that our call to operator[] will call the const version), the second to remove the const from the const operator[]’s return value.


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Item 3: Use const whenever poss.. 下一篇Item 4: Make sure that objects ..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: