<meta content="text/html; charset=utf-8" http-equiv="CONTENT-TYPE">
<meta content="OpenOffice.org 2.2 (Linux)" name="GENERATOR">
<meta content="freebird" name="AUTHOR">
<meta content="20070510;9550000" name="CREATED">
<meta content="root" name="CHANGEDBY">
<meta content="20070717;14010300" name="CHANGED">
<style type="text/css">
<!--
@page { size: 8.5in 11in; margin: 0.79in }
H1 { margin-top: 0.24in; margin-bottom: 0.23in; line-height: 200%; page-break-inside: avoid }
H1.western { font-family: "Liberation Serif", serif; font-size: 22pt }
H1.cjk { font-family: "DejaVu Sans"; font-size: 22pt }
H1.ctl { font-family: "DejaVu Sans"; font-size: 22pt }
H2 { margin-top: 0.18in; margin-bottom: 0.18in; line-height: 173%; page-break-inside: avoid }
H2.western { font-family: "Cambria", serif; font-size: 16pt }
H2.cjk { font-family: "宋体", "SimSun"; font-size: 16pt }
H2.ctl { font-family: "Times New Roman", serif; font-size: 16pt }
P { margin-bottom: 0.08in }
-->
</style>
操作符重载
保持重载操作符的自然语义
首先我们理解int变量的赋值语句,它可以成为我们的参照物。
int a(7);
int b(8);
int c(9);
c=a=b;
编译器会先用b的值赋给a变量,并且a=b的表达式的值就是此时a的值,然后表达式的值会再赋给c变量。
下面是另一种用法:
(a=b)=c;
这时候,b的值赋给了a,然后c的值将赋给(a=b)表达式,实际上赋给了a变量。
以上两种情况我们称为连锁赋值,如果你不用刮号改变顺序的话,编译器将使用右结合律来对连锁赋值执行运算。
假如你写了一个类Widget,并提供自己的operator =和operator +=函数,为了同样支持上面的两种用法,你需要让函数返回对象本身的引用,return *this;。
成员还是非成员
基本原则:
operator =、operator () 、operator [] 、operator -> 应该是成员函数
>>和<<始终是非成员函数,必要时可以成为友元函数
其他操作符:
如果函数必须是虚函数,那就成为成员函数
如果它可以使用类的其他公有成员函数来实现,就让它成为非成员函数或者非友元函数
如果它需要操作数能够向它的左参数转型,它不能成为成员函数。
流操作符为什么要成为非成员函数,比如我们现在有个类使用成员函数形式来实现:
class A
{
public:
ostream& operator <<(ostream& stream) const
{
return stream;
}
istream& operator >>(istream& stream)
{
return stream;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
a<<cout;
return 0;
}
我们看一下a<<cout,这违反了c++中的使用习惯,通常要想把一个对象的值输出到流对象中,我们应该使用cout<<a,但这里cout<<a会出错,因为operator <<是A类的成员函数,而成员函数的限制是对象一定要出现在函数的左边。所以它们不能成为成员函数。
“如果它需要操作数能够向它的左参数转型,它不能成为成员函数”这句话是不是比较费解?让我们看看operator +的例子。
假如你提供了一个类A,该类有一个成员函数operator +,那么当遇到下面的代码时,编译器将报错:
A a,b;
a=10+b;
10是个整形常量,它并没有提供operator +(A const& a)这样的重载函数,编译器会说找不到这种形式的操作符函数。当你提供了一个非成员函数operator+(int, A const& a),上面这段代码就可以正常工作了。
不要重载&&、||和,操作符
编译器对&&和||构成的表达式的顺序采用了左结合律。比如&&的左边表达式的值如果是false,那么&&右边的表达式就不会求值,而直接给出exp1 && exp2 的值为false.
但是一旦你重载了&&,这个特性将消失,所有表达式都将被求值,并且求值顺序是不一定的。
默认,操作符也采用了左结合律,但是不同于&&和||,每个子表达式的值都会被求出来。
同样的问题,当你重载了,操作符后,求值的顺序变得不确定。
分享到:
相关推荐
实现操作符重载实现操作符重载实现操作符重载实现操作符重载实现操作符重载
C++ 操作符重载简单小例子
这是我对书上一道C++例题改编的,意在说明操作符重载的使用,我举的例子就是分数,包括分数的输入,输出,分数的加法
快速排序算法测试,操作符重载,模板应用. 在VS2005下调试通过
c++操作符重载c++操作符重c++操作符重载载
cpp入门教程-操作符重载: 主要内容为友元和操作符重载主要内容为友元和操作符重载主要内容为友元和操作符。
1.类 指的是一段 程序代码 就像C中的 函数一样 它是独立的 而数据类型 就是指你输入的数据的性质是什么样的 比如说一个人 衣服好比是类 而 数据类型就是你是男的还是女的?? 呵呵 2.我知道常用的几中一 直接在程序中...
C++操作符重载手册
包含基本分数类,重载加减乘除约分同分和六目比较运算的分数类,同时包含派生整数类。
Set类,+-*=[]<<>>等操作符的重载 //可以实现集合的并、交、差等操作
c++操作符重载详解,有详细的代码~已经调试好了可以运行的~
C++操作符重载专题 超高清 超详细 让你完全掌握C++操作符重载
vc++函数重载与操作符重载 虚函数 纯虚函数和抽象类
包含C++的算术操作符,关系操作符,下标操作符,自增操作符和自减操作符
一个对时间进行操作的应用程序,可以进行两时间比较,加、减, 主要是应用操作符重载!
C++操作符重载实例(加法操作符实现两个实数相加),又小,又方便,其它的重载写法可以参照这个,适合初学者
本文介绍了C++特有的操作符重载功能 本文内容完全属于个人见解与参考文现的作者无关,其中难免有误解之处,望指出更正
实例003——操作符重载实现编译多态——复数的加法运算 实例003——操作符重载实现编译多态——复数的加法运算 实例003——操作符重载实现编译多态——复数的加法运算