more effective c++——Item M30 代理类(二)通过代理类识别operator[]的读写操作
来源:互联网 发布:打投做数据是什么 编辑:程序博客网 时间:2024/04/26 23:56
在我们的带引用计数的string类中对于operator[]的操作分为cosnt和非const,const对象调用不会修改string对象的值的函数,并假定非const的operator[]调用时会修改string对象的值,因此非const的operator调用时不管实际上有没有修改string对象的值,都需重新拷贝一份string对象。通过代理类延迟对operator[]的操作可以对读写操作进行识别。
以下为添加代理类的String类的部分实现:
#pragma once#include <cstring>#include <iostream>using namespace std;class String { // class to be used by application developerspublic: class proxychar { public: proxychar(const int index, String &rhl); proxychar &operator= (const proxychar &rhl); proxychar &operator= (const char c); friend ostream& operator<<(ostream &os, const proxychar &rhl) { return os << rhl.m_str.value->data[rhl.m_index]; } private: String &m_str; int m_index; }; String(const char *value = ""); const proxychar& operator[](int index) const; proxychar& operator[](int index); friend proxychar; String(const char *value = ""); const proxychar& operator[](int index) const; proxychar& operator[](int index);private: // class representing string values struct StringValue : public RCObject { char *data; StringValue(const char *initValue); StringValue(const StringValue& rhs); void init(const char *initValue); ~StringValue(); }; RCPtr<StringValue> value;};const String::proxychar& String::operator[](int index) const{ return String::proxychar(index,const_cast<String &>(*this));}String::proxychar& String::operator[](int index){ return String::proxychar(index, *this);}String::proxychar::proxychar(const int index, String &rhl):m_str(rhl),m_index(index){}String::proxychar& String::proxychar::operator = (const proxychar &rhl){ if (m_str.value->isShared()) { m_str.value = new StringValue(m_str.value->data); } m_str.value->data[m_index] = rhl.m_str.value->data[rhl.m_index]; return *this;}String::proxychar & String::proxychar::operator=(const char c){ if (m_str.value->isShared()) { m_str.value = new StringValue(m_str.value->data); } m_str.value->data[m_index] = c; return *this;}
在这里,在调用operator[]时,我们不直接返回char,而是返回一个char的代理类的对象,该类持有string类的引用,并且封装了char所需要的大部分操作,然后在对char的操作,比如operator=中对string进行拷贝,在operator<<中直接返回string的下标.
当需要输出String[index]时,String类先返回一个proxychar对象,然后调用proxychar类的operator<<操作符,此时String类不需要进行拷贝。
当需要修改String[index]时,String类先返回一个proxychar对象,然后调用proxychar类的operator=操作符,此时String类判断是否需要进行拷贝,然后进行赋值
但是这个类存在一些缺陷:
1.需要自己实现原始类(这里是char类型)的所有操作,如operator<<操作符,operator=操作符,operator>>,operator&()操作符等
2.由于每次对string进行索引时,都要构建proxychar的临时对象,存在额外的开销
3.在隐式类型转换上,proxy类即使声明了自己的隐式类型转换函数,将proxy转换为其代理的类型,仍然存在很多类型转换的问题,为了避免后续的类型转换错误,一般的做法是直接将构造函数直接声明为explicit。
class TVStation {public:TVStation(int channel);//...};void watchTV(const TVStation& station, float hoursToWatch);watchTV(10, 2.5); // 借助于 int 到 TVStation 的隐式类型转换Array<int> intArray;intArray[4] = 10;watchTV(intArray[4], 2.5);//失败,不可以通过int的代理类转换为TVStation类
- more effective c++——Item M30 代理类(二)通过代理类识别operator[]的读写操作
- more effective c++——Item M30 代理类(一)多维数组的实现
- More Effective C++ Item M30:代理类
- more effective c++——Item M30 代理类(三)隐式类型转换与代理类
- more effective c++——Item M29 引用计数(二)带静态成员变量的rfstring类实现
- more effective c++ Item M4 书上写的代理类实现不了,需要修改一下哟
- 【more effective c++读书笔记】【第5章】技术(6)——Proxy classes(代理类)
- more effective c++——Item M29 引用计数(三)带引用计数的基类的实现
- more effective c++——Item M29 引用计数(一)简略的rfstring类设计和写时拷贝
- operator new和 new operator的区别(More Effective C++_8(运算符))
- More Effective C++:Item 27
- More Effective C++:Item 27
- Scrapy爬虫(二)——自定义Item和代理访问的爬虫
- 《more effective c++》Item M1:指针与引用的区别
- 《More Effective C++》 Item M1:指针与引用的区别
- 《More Effective C++》学习心得(二)
- read Item 25 of《More Effective C++》
- More Effective(二)操作符
- ISE综合后得到的RTL图如何与硬件对应起来,怎么知道每个element的功能
- vulkanAPI学习笔记(零)
- Spring JdbcTemplate批量更新速度很慢的问题
- 数据库
- Unity3D铰链关节的简单实例
- more effective c++——Item M30 代理类(二)通过代理类识别operator[]的读写操作
- 555. Split Concatenated Strings
- 多线程学习01:Semaphore信号量的用法
- Python第二坑--安装库
- ChildrenToFitScreen.cs
- Codeforces Round #411 (Div. 1)(A~D)题解
- 关于jsp页面向mysql数据库插入中文记录
- python基础练习:用户登录实验源码
- PHP(PDO)-MySQL-jQuery Ajax getJSON综合示例