利用using简化受限的proxy代码

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

让我们的一切从代码开始吧,简单起见,代码省略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这样的特性,但是这种期望是在是不令人乐观。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航