让我们的一切从代码开始吧,简单起见,代码省略std名字空间: class MyObject { object_id obj_id_; class_id class_id_; map<property_id, boost::any> 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内部不一致。 于是,我只能这么干: 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<property_id, boost::any> { typedef map<property_id, boost::any> ContType; object_id obj_id_; class_id class_id_; //map<property_id, boost::any> 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在这里很好的解决了我的问题,然而,他还是不能取代proxy。using无法让我有选择的代理函数的特定重载版本,例如我想公开const_iterator begin() const;而不公开iterator begin()就不能通过using实现。真希望C++会在语言层面支持proxy、delegate、reflection这样的特性,但是这种期望是在是不令人乐观。 
|