More Effective C++ 条款30 Proxy classes(替身类,代理类)
2015-10-09 14:47
387 查看
1. 所谓代理类(proxy class),指的是"它的每一个对象都是为了其他对象而存在的,就像是其他对象的代理人一般".某些情况下用代理类取代某些内置类型可以实现独特的功能,因为可以为代理类定义成员函数而但却无法对内置类型定义操作.条款5就展示了一个使用代理类阻止隐式类型转换的例子.
2. 实现二维数组.
C++没有提供分配动态二维数组的语法,因此常常需要定义一些类(模板实现这些功能),像这样:
View Code
2). 将proxy class传递给接受"references to non-const objects"的函数.
假设有一个swap函数用于对象两个char的内容:
那么将无法将CharProxy做参数传递给swap,因为swap的参数是char&,尽管CharProxy可以转换到char,但由于抓换后的char是临时对象,仍然无法绑定到char&,解决方法似乎只有对swap进行重载.
3). 通过proxy cobjects调用真实对象的member function.
如果proxy class的作用是用来取代内置类型,那么它必须也应该对内置类型能够进行的操作进行重载,如++,+=等,如果它用来取代类类型,那么它也必须具有相同成员函数,使得对该类类型能够进行的操作同样也能够施行于proxy class.
4). 隐式类型转换.
proxy class要具有和被代理类型相同的行为,通常的做法是重载隐式转换操作符,正如条款5对proxy class的使用那样,proxy class可以利用"用户定制的隐式类型转换不能连续实行两次"的特点阻止不必要的隐式类型转换,proxy class同样可能因为这个特点而阻止用户需要的隐式类型转换.
5. 评估
proxy class的作用很强大,像上面所提到的实现多维数组,区分operator[]的读写操作,压抑隐式类型转换等,但是也有其缺点,如果函数返回proxy class对象,那么它僵尸一个临时对象,产生和销毁它就有可能带来额外的构造和析构成本,此外正如4所讲,proxy class无法完全代替真正对象的行为,尽管大多数情况下真正对象的操作都可由proxy class完成.
2. 实现二维数组.
C++没有提供分配动态二维数组的语法,因此常常需要定义一些类(模板实现这些功能),像这样:
char * String::CharProxy::operator&() { //如果正在使用共享内存,就开辟新内存并复制数据结构 if (theString.value->isShared()) { theString.value = new StringValue(theString.value->data); } //由于有外部指针指向它,因此有被篡改风险,禁止使用共享内存 theString.value->markUnshareable(); return &(theString.value->data[charIndex]); }
View Code
2). 将proxy class传递给接受"references to non-const objects"的函数.
假设有一个swap函数用于对象两个char的内容:
void swap(char& a, char& b);
那么将无法将CharProxy做参数传递给swap,因为swap的参数是char&,尽管CharProxy可以转换到char,但由于抓换后的char是临时对象,仍然无法绑定到char&,解决方法似乎只有对swap进行重载.
3). 通过proxy cobjects调用真实对象的member function.
如果proxy class的作用是用来取代内置类型,那么它必须也应该对内置类型能够进行的操作进行重载,如++,+=等,如果它用来取代类类型,那么它也必须具有相同成员函数,使得对该类类型能够进行的操作同样也能够施行于proxy class.
4). 隐式类型转换.
proxy class要具有和被代理类型相同的行为,通常的做法是重载隐式转换操作符,正如条款5对proxy class的使用那样,proxy class可以利用"用户定制的隐式类型转换不能连续实行两次"的特点阻止不必要的隐式类型转换,proxy class同样可能因为这个特点而阻止用户需要的隐式类型转换.
5. 评估
proxy class的作用很强大,像上面所提到的实现多维数组,区分operator[]的读写操作,压抑隐式类型转换等,但是也有其缺点,如果函数返回proxy class对象,那么它僵尸一个临时对象,产生和销毁它就有可能带来额外的构造和析构成本,此外正如4所讲,proxy class无法完全代替真正对象的行为,尽管大多数情况下真正对象的操作都可由proxy class完成.
相关文章推荐
- C语言fillpoly函数详解
- c++运算符使用友元函数重载问题
- 爬爬爬之路:C语言(二) 入门篇2
- VC++常用代码总结
- c++类中静态函数不能调用类中的非静态函数原因
- VC++ MFC 常用技巧
- Virtual Studio C++ Version Macro - _MSC_VER
- C/C++---printf/cout 从右至左压栈顺序实例详解
- 使用C语言描述静态链表和动态链表
- Visual C++学习笔记1:一定要注意ANSI和UNICODE差额
- 划分树C++版百度百科模板
- 字符转二进制_C++实现
- C++第四课 选择结构
- C++ string
- C/C++语言中关于const用法的总结
- C++中using的作用
- 探讨C++内存回收
- C语言实现二叉树-02版
- C++ 文件名和 路径
- 链式循环队列实现(C语言)