最近在看GoF的《设计模式》,在此之前看了John Vlissides的《设计模式沉思录》,在“沉思录”P42页脚注中,作者提到

“在C++中这样的定义是难以通过任何强制性的方法实现的[Schmidt96a]。例如,只要用一条简单的#define语句来把private定义为public,我们就可以让所有私有成员变成共有成员。避免这种篡改的一种方法是根本不在头文件中定义成员变量。相反,我们把成员变量和其他机密的实现细节定义在另一个单独的、不公开的头文件中。一个与此紧密相关的模式是BRIDGE……”

,作者可谓点到即止。

而在《设计模式》P102页的下边部分

“Carolan[Car89]用‘常露齿嘻笑的猫’(Cheshire Cat)描述这一分离机制。在C++中,Implementor类的类接口可以在一个私有的头文件中定义,这个文件不提供给客户。这样你就对客户彻底隐藏了一个类的实现部分。”

什么是‘常露齿嘻笑的猫’(Cheshire Cat)?(转自:http://baike.soso.com/h7921075.htm?sp=l7921076)

柴郡猫(Cheshire cat)是英国作家刘易斯·卡罗尔(Lewis Carroll,1832-1898)创作的童话《爱丽丝漫游奇境记(Alice's Adventure in Wonderland)》中的虚构角色,形象是一只咧着嘴笑的猫,拥有能凭空出现或消失的能力,甚至在它消失以后,它的笑容还挂在半空中。卡罗尔创作这个角色的灵感可能来源于英国俗语“笑得像一只柴郡猫”(grin like a Cheshire cat),该俗语的来源众说纷纭,有的说是柴郡盛产一种做成笑脸猫形状的奶酪,有的说是当地有一位贵族,他的大衣袖子上画了一只狮子,狮子画得很糟糕,倒像一只笑脸猫,还有人说是来自柴郡一位叫Caterling的笑容丑陋的护林员的绰号。《爱丽丝漫游奇境记》里的柴郡猫出现于第六章,出场时坐在公爵夫人家的壁炉前,爱丽丝看到它一直在咧着嘴笑,便问公爵夫人为什么它在笑,公爵夫人告诉她因为那是一只柴郡猫。"Please would you tell me,"said Alice,a little timidy,for she was not quite sure whether it was good manners for her to speak first,"why your cat grins like that?""It's a Cheshire cat,'said the Duchess,"and that's why." 离开公爵夫人家后,柴郡猫指给了爱丽丝去三月兔和帽匠家的路,后来在女王的槌球赛场上又在爱丽丝面前出现,连动辄叫喊砍头的女王也对它无计可施。或许由于其神秘感,这只总是咧嘴微笑着、不参与任何事而保持冷眼旁观的柴郡猫一直是《爱丽丝漫游奇境记》中最受欢迎的角色之一。后人在戏仿《爱丽丝漫游奇境记》的作品中经常有这只猫的身影,例如漫画《红茶王子》的一部番外篇和《樱兰高中HOST部》的一集;吉卜力的动画电影《龙猫》中咧着嘴笑的猫巴士,《潘多拉之心》中的笑面猫也受了柴郡猫的形象影响。

那Cheshire Cat到底讲的是什么回事呢?去http://www.acm.org/sigs查,未果。按照GoF的参考文献上说,Cheshire Cat来自于John Carolan在1989年的文章“Constructing bullet-proof classes”,索性去Google搜这篇文章吧~

没找到原文,但找到了篇引用原文的文章:http://wiki.hsr.ch/Prog3/files/overload72-FINAL_DesigningHeaderFiles.pdf

Cheshire Cat
● A private “representation” class is written that embodies the
same functionality and interface as the naïve class – however,
unlike the naïve version, this is defined and implemented
entirely within the implementation file. The public interface of
the class published in the header is unchanged, but the private
implementation details are reduced to a single member variable
that points to an instance of the “representation” class – each
of its member functions forwards to the corresponding function
of the “representation” class.
● The term “Cheshire Cat” is an old one, coined by John Carollan
over a decade ago [2]. Sadly it seems to have disappeared from
use in contemporary C++ literature. It appears described as a
special case of the “Bridge” pattern in Design Patterns [3], but
the name “Cheshire Cat” is not mentioned. Herb Sutter [4]
discusses it under the name “Pimpl idiom”, but considers it only
from the perspective of its use in reducing physical
dependencies. It has also been called “Compilation Firewall”.
● Cheshire Cat requires “boilerplate” code in the form of
forwarding functions that are tedious to write and (if the
compiler fails to optimise them away) can introduce a slight
performance hit. It also requires care with the copy semantics
(although it is possible to factor this out into a smart pointer
[5]). As the relationship between the public and implementation
classes is not explicit it can cause maintenance issues.

译文如下:

柴郡猫1、一个私有“展示”类被写成与朴实类包含相同函数和接口,但是不朴实版本的类不同的是,它(私有“展示”类)整个被在一个实现文件中定义和实现。在头文件中发布的类的公共接口不变,然而私有实现的细节被缩减成一个单个成员变量,该变量指向一个“展现”类的实例,它(在头文件中发布的类)的所有成员函数(调用)都被转送(“委托”更恰当些~)给“展示”类的相应函数。2、“柴郡猫”(Cheshire Cat)是一个旧的说法,由John Carollan 在10年前创造的。不幸的是这种说法貌似在现代C++文献中已经不再使用了。它被描述成《设计模式》中“Bridge”模式的一种特殊形式,但是“柴郡猫”(Cheshire Cat)没有被提及。Herb Sutter以“Pimpl idiom”名字讨论过它,但是只是从它在减少物理依赖的作用方面关注了它。它同时被叫做“编译防火墙”。3、“柴郡猫”(Cheshire Cat)需要转送函数形式的“照本宣科”的代码(“硬编码”),这些代码通常冗长且(如果编译器没有将它们优化掉的话)会带来性能上的下降。它也需要关注复制语义(尽管可以将这点提取到智能指针中)。由于公共和实现类之间的关系不是显式的,所以它(Cheshire Cat)可能引起维护上的问题。

Cheshire Cat的示例代码如下:

// cheshire_cat.hpp Cheshire Cat -
// implementation hiding example
#ifndef INCLUDED_CHESHIRE_CAT_HPP_ARG_20060303
#define INCLUDED_CHESHIRE_CAT_HPP_ARG_20060303
#include <string>
#include <utility>
namespace cheshire_cat
{
class telephone_list
{
public:
telephone_list(const std::string& name);
~telephone_list();
std::string get_name() const;
std::pair<bool, std::string>
get_number(const std::string& person)
const;
telephone_list&
add_entry(const std::string& name,
const std::string& number);
private:
class telephone_list_implementation;
telephone_list_implementation* rep;
telephone_list(const telephone_list& rhs);
telephone_list& operator=
(const telephone_list& rhs);
};
}
#endif

朴实示例代码如下:

// naive.hpp - implementation hiding
// example.
#ifndef INCLUDED_NAIVE_HPP_ARG_20060303
#define INCLUDED_NAIVE_HPP_ARG_20060303
#include <string>
#include <utility>
#include <map>
#include <algorithm>
#include <ctype.h>
namespace naive
{
/** Telephone list. Example of implementing a
*telephone list using a naive implementation.
*/
class telephone_list
{
public:
/** Create a telephone list.
* @param    name    The name of the list.
*/
telephone_list(const std::string& name);
/** Get the list's name.
* @return   the list's name.
*/
std::string get_name() const;
/** Get a person's phone number.
* @param    person  The person's name
* (must be an exact match)
* @return   pair of success flag and (if
* success) number.
*/
std::pair<bool, std::string>
get_number(const std::string& person)
const;
/** Add an entry. If an entry already
* exists for this person it is overwritten.
*
*   @param  name    The person's name
*   @param  number  The person's number
*/
telephone_list&
add_entry(const std::string& name,
const std::string& number);
private:
typedef std::map<std::string,
std::string> dictionary_t;
std::string  name;
dictionary_t dictionary;
telephone_list(const telephone_list& rhs);
telephone_list& operator=
(const telephone_list& rhs);
};
}
#endif

可以发现,如果用户使用

#define private public

则朴实代码中的所有private权限的变量将全部可见!完全无法隐藏!

而Cheshire Cat代码中,由于没有在文件中定义成员变量(至少没有定义那么多敏感成员变量),所以Cheshire Cat代码不会暴露实现细节,顶多是暴露了

class telephone_list_implementation;
telephone_list_implementation* rep;

而如果class telephone_list_implementation的实现是在一个lib或dll文件中,那么用户根本无法通过

#define private public

方式使class telephone_list_implementation的细节暴露!因为用户没有class telephone_list_implementation的源代码……

用户拿到的最多是telephone_list_implementation* rep,而无法暴露telephone_list_implementation* rep的细节。

关于《设计模式》与《设计模式沉思录》中提到的“常露齿嘻笑的猫”(Cheshire Cat)的说明相关推荐

  1. 关于《设计模式》与《设计模式沉思录》中提到的“常露齿嘻笑的猫”(Cheshire Cat)的说明...

    最近在看GoF的<设计模式>,在此之前看了John Vlissides的<设计模式沉思录>,在"沉思录"P42页脚注中,作者提到 "在C++中这样 ...

  2. C++沉思录上提到的一道练习题及其源码实现

    题目大意(具体问题可参考C++沉思录第九章): 现实中,一张图片,可以给予添加一层又一层片框,也可以和其他的图片组合在一块,或横,或竖,--, 如下图所示: 普通的图片: wjj lqm lqmwjj ...

  3. 产品沉思录精选:交易平台的金字塔进阶

    本文根据上一期沉思录回顾的调研结果,为大家翻译整理了交易平台的金字塔进阶专题. 作为本年回顾类型的最后一期,想随着这个话题给大家分享fonter在新一期沉思录中介绍的概念depth year &quo ...

  4. 产品沉思录精选:为何知识资本将胜过金融资本

    <明朝那些事儿>中,有一个章节专门是讲王阳明如何找到「知行合一」这个重要的方法论的 -- 在此之前,他遵循先辈的理学,不停地「格物」但却最终没有见到什么效果,因为有「知识」的人并不注重行动 ...

  5. 设计模式调优-性能设计沉思录(10)

    JAVA调优系列文章 JVM调优全面探讨-性能设计沉思录(1)_luozhonghua2000的博客-CSDN博客 JVM GC回收和内存分配优化-性能设计沉思录(2)_luozhonghua2000 ...

  6. 《设计模式沉思录》—第2章2.4节访问权限

    本节书摘来自异步社区<设计模式沉思录>一书中的第2章,第2.4节访问权限,作者[美]John Vlissides,更多章节内容可以访问云栖社区"异步社区"公众号查看. ...

  7. 《设计模式沉思录》分享

    书籍信息 书名: 设计模式沉思录 原作名: Pattern Hatching: Design Patterns Applied 豆瓣评分: 8.6分(78人评价) 内容简介 本书作者是设计模式的开山鼻 ...

  8. 设计模式沉思录读后感

    引言:前段时间参加一个大学生服务外包比赛,一个月类疯狂的碼代码亚,终于在完成一个小型的web项目,接下来听老师分配,要学习一下文件目录管理,给了我一本<设计模式沉思录>,让这几天先看一遍, ...

  9. 设计模式沉思录读后感2

    暑假在家待了8天,回来就不出意外的开始了我新的代码生活,这个学期任务是文件管理和数据挖掘,据说挺有挑战的哦,不过我喜欢,有难度才能学到更多东西嘛. 回家后基本上没看什么书,就在回家的火车上看了几个设计 ...

最新文章

  1. USG防火墙telnet实验
  2. 下一次工业革命:计算生物学与生物平台
  3. ZZULIOJ 1918: G 【二分图匹配】
  4. 第3 章体系结构(Architecture)
  5. GPU编程语言选择(OpenCL、CUDA 与C++ AMP)
  6. 浅谈SAP系统的预测模型与预测公式
  7. 码云上传代码添加标签_[Android] 发布码云(Gitee)项目到JitPack(最全完整流程)
  8. 搭建分布式 ASP.NET Core Web
  9. LeetCode 1668. 最大重复子字符串
  10. hbuilder php xdebug,Hbuilder使用xdebug配置php断点调试
  11. Android-解决ViewFlipper与ScrollView滑动响应事件拦截的问题【转】
  12. C/C++调用java---JNI常用函数
  13. python split拆分字符串_python实现字符串完美拆分split()的方法
  14. Centos 6.6 Docker安装(内网坏境)
  15. 中兴 F607 光猫超级管理用户查看
  16. 不允许对系统目录进行即席更新_不被允许再更新安卓系统,华为手机用户怎么办?华为回应!...
  17. MySQL 索引介绍!
  18. 解决clion多个mian函数问题
  19. 王和勇计算机软件,图像空间中的鉴别型局部线性嵌入方法
  20. android qq消息数 拖拽动画,史上最详细仿QQ未读消息拖拽粘性效果的实现

热门文章

  1. 中文文本情感分类实战(weibo_senti_100k为数据集)
  2. 佳能相机照片恢复的软件
  3. Flutter 关于图片的保存以及权限申请及安卓配置
  4. 字母数字下划线常用正则表达式~
  5. 项目国际化(i18n)
  6. 浮动广告(页面中一张广告图片不断的变化位置)
  7. 故障:部署 Exchange SU 后不能登录到 OWA 或 ECP
  8. Xilinx HLS 仿真报错ERROR: [SIM 211-100] CSim failed with errors.
  9. Epub360教你如何制作报纸翻页式创意招聘H5?
  10. 数据整合基础知识介绍