网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > C/C++
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.数据结构学习(C++)之递归.
.送给初学者的礼物:C++游戏编程起.
.C++ Builder 动作对象.
.修正后的“模拟windows 日期/时间.
.深入浅出Win32多线程程序设计之综.
.C++箴言:在资源管理类中准备访问.
.use Assembly to call a method.
.C++/CLR泛型与C++模板的对比.
.在CB环境中实现在菜单中显示历史.
.灵活运用c语言实现高级功能.
.用户界面设计风格说明上.
.传递焦点的五种方法.
.QQ本地密码验证破解.
.限次程序C语言源码.
.C语言的结构和C++类的异同.
.C++还能重新辉煌吗?C++复杂性的.
.GNU 编译器家族 GCC 内部探密.
.实例讲解.
.C++语言代码检查工具PC-Lint四步.
.经典c程序100例==61--70.

C++中通过重载避免隐式类型转换

发表日期:2008-3-8



  以下是一段代码,假如没有什么不平常的原因,实在看不出什么东西:

class UPInt { // unlimited precision
 public: // integers 类
 UPInt();
 UPInt(int value);
 ...
};

//有关为什么返回值是const的解释,参见Effective C++ 条款21

const UPInt operator+(const UPInt& lhs, const UPInt& rhs);
UPInt upi1, upi2;
...
UPInt upi3 = upi1 + upi2;
  这里还看不出什么令人惊奇的东西。upi1 和upi2都是UPInt对象,所以它们之间相加就会调用UPInts的operator函数。

  现在考虑下面这些语句:

upi3 = upi1 + 10;
upi3 = 10 + upi2;
  这些语句也能够成功运行。方法是通过建立临时对象把整形数10转换为UPInts(参见条款19)。

  让编译器完成这种类型转换是确实是很方便,但是建立临时对象进行类型转换工作是有开销的,而我们不想承担这种开销。就象大多数人只想从政府那里受益而不想为此付出一样,大多数C++程序员希望进行没有临时对象开销的隐式类型转换。但是在计算领域里发生不了赤字现象,我们如何能这么做呢?

  让我们回退一步,熟悉到我们的目的不是真的要进行类型转换,而是用UPint和int做为参数调用operator。隐式类型转换只是用来达到目的的手段,但是我们不要混淆手段与目的。还有一种方法可以成功进行operator的混合类型调用,它将消除隐式类型转换的需要。假如我们想要把UPInt和int对象相加,通过声明如下几个函数达到这个目的,每一个函数有不同的参数类型集。

const UPInt operator+(const UPInt& lhs, // add UPInt
const UPInt& rhs); // and UPInt
const UPInt operator+(const UPInt& lhs, // add UPInt
int rhs); // and int
const UPInt operator+(int lhs, // add int and
const UPInt& rhs); // UPInt

UPInt upi1, upi2;
...
UPInt upi3 = upi1 + upi2; // 正确,没有由upi1 或 upi2

// 生成的临时对象
upi3 = upi1 + 10; // 正确, 没有由upi1 or 10
// 生成的临时对象
upi3 = 10 + upi2; //正确, 没有由10 or upi2
//生成的临时对象。
  一旦你开始用函数重载来消除类型转换,你就有可能这样声明函数,把自己陷入危险之中:

const UPInt operator+(int lhs, int rhs); // 错误!
  这个想法是合情合理的。对于UPInt和int类型,我们想要用所有可能的组合来重载operator函数。上面只给出了三种重载函数,唯一漏掉的是带有两个int参数的operator,所以我们想把它加上。

  有道理么?在C++中有一条规则是每一个重载的operator必须带有一个用户定义类型(user-defined type)的参数。int不是用户定义类型,所以我们不能重载operator成为仅带有此类型参数的函数。(假如没有这条规则,程序员将能改变预定义的操作,这样做肯定把程序引入混乱的境地。比如企图重载上述的operator,将会改变int类型相加的含义。)

  利用重载避免临时对象的方法不只是用在operator函数上。比如在大多数程序中,你想答应在所有能使用string对象的地方,也一样可以使用char*,反之亦然。同样假如你正在使用numerical(数字)类,例如complex(参见条款35),你想让int和double这样的类型可以使用在numerical对象的任何地方。因此任何带有string、char*、complex参数的函数可以采用重载方式来消除类型转换。

  不过,必须谨记80-20规则(参见条款16)。没有必要实现大量的重载函数,除非你有理由确信程序使用重载函数以后其整体效率会有显著的提高。
上一篇:深入理解C++中的mutable关键字 人气:529
下一篇:在C++中实现.NET风格的委托 人气:449
浏览全部C/C++的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐