刚才猎手在QQ群里问了一个关于auto_ptr的问题:
如何从一个
std::auto_ptr<TMemoryStream> MyStream;
里取得一个“TStream *”类型(VCL中TMemoryStream派生自TStream)的变量?
令狐道:试试 &(*MyStream) 看看
猎手一试:果然可以。令狐,(TStream *)应该也可以的吧
令狐:不行
猎手:为什么
猛禽:运算符重载
令狐:MyStream实际上是一个auto_ptr的Object,不是一个真正的指针。我刚刚给你的操作利用了auto_ptr的operator*重载,而auto_ptr没有也不可能重载 operator (TStream *)
BTW:偶曾经干过为auto_ptr增加重载 operator( T * ) 的事,后来看了Andrei Alexanderscu的《MCD》(其中关于Smart Pointer的那个章节)才发现,这正是一个昨天被我批过的“小技巧”。-_-|||
=====重载的分割线======
C++里像运算符重载这样的东西是很妖的,这也是为什么后来的JAVA/C#都不再提供这样的功能。
因为作了重载,所以我们所看到的这个运算符、以及我们所设想它实现的功能,很可能已经不是它实际上的效果了。
很多问题并不是我们看上去的那个样子——不只是C++,也不止是技术。
C写惯了,怎么也适应不了这个auto_ptr,总觉得自己malloc/free & new/delete更”本质”一点
auto_ptr在c++里还是很有用的/运算符重载的确是个(个人认为)淫蛋,他的本意是“简化”方法的表现,看上去更直观,在一些运算符意义很明确的地方的确看着很爽,但是有时候不如方法名称看的舒服,还容易混淆。
接受学习
关于这个,Scott Meyers在CUJ的一篇文章里写了很多,可惜没时间找出链接。一般而言,并不倾向于操作符重载,尤其是比较抽象的用法和容易混淆的时候,谁知道是:男人+女人=3还是男人*女人=3^0^
唔,Scott Meyers的《EC》/《MEC》也是好书,对很多“小技巧”都有指出问题所在。
操作符重载其实是个好东西。我觉得像Java那样到处都是接口也很不好受。男人+女人=3 这种,纯属对操作符重载的误用,如果谁不幸用到了这样的程序库,只好自认倒霉。C++的操作符重载我认为缺点有2个,一是自由度太高,几乎所有的操作符都能重载,而且返回值参数类型,意义全部都可以改,极易发生误用情形;二是没有“连带”责任,我重载了operator+,却忘记重载operator+=,结果+操作倒是按新规则来了,+=这个意义十分相近的操作却没有,这不论对使用者、开发者来说,都是一种悲哀。(典型的例子就是以前iterator的 &(*) 和 ->)
Java到处都是接口那也是没办法的事,像Python这样的就没必要多接口这么个多余的东东了。运算符重载是个好东东,模板也是,所以我们才要叹息语言的特性难以取舍啊。^O^
爪哇不清楚,不过C#是支持运算符重载的吧,
C#好像是支持,不过跟C++的好像不是一回事。