利用using简化受限的proxy代码和调整访问权

原创 2004年09月13日 11:14:00

    让我们的一切从代码开始吧,简单起见,代码省略std名字空间:
class MyObject {
    object_id obj_id_;
    class_id  class_id_;
    map properties_;
    static const type_dict& getDict();
...
};

    这是个从实际的项目中整理出来的代码,简单的说明一下:properties存放了Object的属性,MyObject底层依赖一个类型系统的支撑,这个类型系统的模型就是type_dict。class_id_是记录一个对象实例所属的类型,obj_id_则是对象实例的ID.
    这个对象的所有属性都是可以从外部访问的,但是,我却不能把properties_公开,因为这样一来的话,外部就可以随便指定一个property_id插入map,而这个property_id也许并没有被当前class_id_所指类型包含,或者,根本就是非法值,这将导致MyObject内部不一致。
    于是,除了完成operator[]和clear这样的实现外,我还要这么干:
public:
const_iterator  begin() const{ return properties_.begin();}
iterator begin() { return properties_.begin();}
...

他们的实现都很简单,只不过是一行:调用properties的相应方法就是了,可我不得不重新写一遍,这是个copy&paste工作,总是让我想打瞌睡,结果,我总是出错,因为我总是忘记做一些必要的修改。如果有类似这样一种语法:
public:
proxy
const_iterator properties_.begin() const;
或者:
proxy properties_.end;
我想我会愉快的多。除了少些一些代码外,关键是代码变得清晰了,程序员通常都是懒惰的,要命的我既懒惰又健忘,保持代码清晰对我而言很重要。于是,代码变成了这样:
class MyObject  : private map {
   typedef map ContType;
   object_id obj_id_;
   class_id  class_id_;
    //map properties_;
   static const type_dict& getDict();
...
};
然后,我可以这么写:
public:
const_iterator  begin() const{ return ContType::begin();}
iterator begin() { return ContType::begin();}
这样看上去语义至少清楚了一些,可是仍然不能让我满意,那个return 语句我还是可能弄错:我把上面两句c&v,然后把begin改成end,结果改漏了一个:(
最终,using达到了我的目的,我决定这么写:
public:
using ContType::begin;
using ContType::end;
using ContType::insert;
这么写不会导致访问权的问题,看,这和我最初设想的proxy properties_.end;多么相似。这样写的好处不仅仅是简单,最重要的是表达出来的语义:转调容器的相同方法。我想任何程序员首先都会相信STL的方法,而不是我写的,即使我的代码只有一行,也可能出错。using 方法如果出错的话,编译时就不会通过。
再想想,using 只是引入一个名字,那么using对typedef的别名应该也有效。来让我们试试这个:
using ContType::iterator;
很好,它可以工作,而且还不必像typedef那样在ContType::iterator前面加一个typename.于是,我决定把map内的类型申明用using的方法引入到MyObject中来,有十几行代码。还好,和using一个成员函数一样,using后面拼写错误的话,编译器立刻就会报错。

我似乎把这个问题解决的很好了,只是还有一点小麻烦:我代理了大部分map的方法,引入map的typedef。其实只有map的swap、operator[]等等少数几个方法需要修改,可是我却要为其他部分写上几十行代码。回到我的目的上来:我只是要防止某些外部对MyObject的修改,避免导致内部不一致而已。结果,我不得不把一大堆typedef和const方法也using了个遍。增加了代码长度倒是其次,它扰乱了我的视线。直观的,别人会以为我是因为需要这些方法,所以代理了他们,但真实的涵义却是:我不关心他们(像count这种东西,我真的不知道是不是需要暴露出来),所以还是让他们保持原样。这种直观的隐喻和真实意图之间的矛盾,让我担心总有一天他会骗倒某个人。还有更好的办法吗?
再让我们看这样一段代码:
struct A{ void fun(){} };
class B : public A { using A::fun;};

试试这一句:B().fun();
编译出错!报告不能访问私有成员。这意味着我们我们能够改变一些基类成员的访问权!实际上,这种访问限制既可以放宽,也可以加强,这太好了!于是我的MyObject可以变成这样:
class MyObject  : public map {
   typedef map ContType;
   using ContType::operator[];//这里,禁止访问map的clear和operator[]
   using ContType::clear;   
  public:
   void clear();
...
};
虽然我在public中也定义了void clear(),但这和悄悄的覆盖行为不同,using ContType::clear;  强烈的表达出关闭基类clear的语义。
这种方法我只需要写几行代码,而且更容易让我们的视线集中,还可以偷更多的懒。
这里有个小小的不足,如果我用MyObject().map::clear()这样的方法,就可以合法的调用map::clear了。不过这基本上可以认为是hack手法,不必过分去关心的。

using在这里很好的解决了我的问题,然而,他还是不能取代proxy。using无法让我有选择的代理函数的特定重载版本,例如我想公开const_iterator  begin() const;而不公开iterator begin()就不能通过using实现。真希望C++会在语言层面支持proxy、delegate、reflection这样的特性,但是这种期望是在是不令人乐观。

图像处理之简化色彩(含OpenCV代码)

图像处理之简化色彩(含OpenCV代码)
  • qq78442761
  • qq78442761
  • 2017年03月11日 21:50
  • 1773

RBM(受限玻尔兹曼机)

RBM(受限玻尔兹曼机) http://www.cnblogs.com/xiaokangzi/p/4492466.html 基于能量模型 (EBM) 基于能量模型将关联到...
  • zdy0_2004
  • zdy0_2004
  • 2015年05月17日 22:02
  • 15959

《机器学习实战》利用PCA来简化数据

=====================================================================   《机器学习实战》系列博客是博主阅读《机器学习实战》这本...
  • Gamer_gyt
  • Gamer_gyt
  • 2016年05月15日 19:08
  • 2701

Java 代码简化系列 (一)

Java趣味短码 - (第一节) 今天跟公司的童鞋聊天的时候,谈到了关于短码和代码的精简的方式,所以整理出来。 需求很简单。 首先定义一个类 class Item{ public in...
  • ttch
  • ttch
  • 2013年01月23日 23:11
  • 1848

RBM(受限玻尔兹曼机)原理及代码

本文转自http://blog.csdn.net/zdy0_2004/article/details/45798223,虽然源贴也是转载的,转自http://www.cnblogs.com/xiaok...
  • xingzhedai
  • xingzhedai
  • 2016年11月07日 17:15
  • 3247

受限的用户SHELL环境

有些特殊情况下需要实现将系统内普通用户限定在指定目录下,并且只能使用系统管理员设定的命令。lshell就是实现这样功能的一个神器。 lshell提供了一个针对每个用户可配置的限制性shell,lsh...
  • savior141
  • savior141
  • 2017年05月06日 22:08
  • 229

Android通过反射和注解简化代码编写(一)

随着应用复杂度增加,后期的应用更倾向于模块化、插件化来尽量减少主程序的容量,对此有几种方法来解决:1.使用so来封装共同模块,通过加载库的形式实现代码共享2.使用jar形式跟so一样,不过容易被反编译...
  • jwzhangjie
  • jwzhangjie
  • 2014年02月13日 15:01
  • 5195

解决VMware 虚拟机中的网络连接出现”受限制或无连接“问题的方法

基本情况: 主机(宿主机):Windows 7 旗舰版(64位) VMware虚拟机:Windows XP Pro SP3 注意:后续提到主机就是Windows 7主机,实体机器。虚拟机指的...
  • yudi100
  • yudi100
  • 2015年01月06日 16:28
  • 7306

受限玻尔兹曼机(RBM)学习笔记(一)预备知识

去年 6 月份写的博文《Yusuke Sugomori 的 C 语言 Deep Learning 程序解读》是囫囵吞枣地读完一个关于 DBN 算法的开源代码后的笔记,当时对其中涉及的算法原理基本不懂。...
  • peghoty
  • peghoty
  • 2014年02月13日 23:36
  • 52310

利用Powershell Empire和CVE-2016-0189攻击用户的IE浏览器

前言 Empire(http://www.powershellempire.com/)是一个PowerShell后期漏洞利用代理工具,它建立在密码学、安全通信和灵活的架构之上。Empire实现了...
  • moonhillcity
  • moonhillcity
  • 2016年10月21日 00:05
  • 1489
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用using简化受限的proxy代码和调整访问权
举报原因:
原因补充:

(最多只允许输入30个字)