`
yangyou230
  • 浏览: 1648505 次
文章分类
社区版块
存档分类

六操作符重载

 
阅读更多
<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.

但是一旦你重载了&&,这个特性将消失,所有表达式都将被求值,并且求值顺序是不一定的。

默认,操作符也采用了左结合律,但是不同于&&和||,每个子表达式的值都会被求出来。

同样的问题,当你重载了,操作符后,求值的顺序变得不确定。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics