网站导航:首页 -> 软件水平考试 -> 软件水平考试指导 -> C++的算符重载

C++的算符重载

  算符重载的作用是什么?它允许你为类的用户提供一个直觉的接口。 算符重载允许c/c++的运算符在用户定义类型(类)上拥有一个用户定义的意义。重载的算符是函数调用的语法修饰:   
class fred { 
 public:    // ... 
}; 
#if 0           // 没有算符重载: 
fred add(fred, fred); 
fred mul(fred, fred); 
fred f(fred a, fred b, fred c) 

 return add(add(mul(a,b), mul(b,c)), mul(c,a)); // 哈哈,多可笑... 

#else   // 有算符重载: 
fred operator+ (fred, fred); 
fred operator* (fred, fred); 
fred f(fred a, fred b, fred c) 

 return a*b + b*c + c*a; 

#endif 
 
  算符重载的好处是什么? 
  通过重载类上的标准算符,你可以发掘类的用户的直觉。使得用户程序所用的语言是面向问题的,而不是面向机器的。 最终目标是降低学习曲线并减少错误率。 
 
  有什么算符重载的实例?这里有一些算符重载的实例: 
mystring + yourstring 可以连接两个 std::string 对象 
mydate++ 可以增加一个 date 对象 
a * b 可以将两个 number 对象相乘 
a[i] 可以访问 array 对象的某个元素 
x = *p 可以反引用一个实际“指向”一个磁盘记录的 'smart pointer' —— 它实际上在磁盘上定位到 p 所指向的记录并返回给x。 

  但是算符重载使得我的类很丑陋;难道它不是应该使我的类更清晰吗?算符重载使得类的用户的工作更简易,而不是为类的开发者服务的! 考虑一下如下的例子: 
class array { 
 public: 
int& operator[] (unsigned i); 
}; 
inline 
int& array::operator[] (unsigned i) 
{   // ... 

  有些人不喜欢operator关键字或类体内的有些古怪的语法。但是算符重载语法不是被期望用来使得类的开发者的工作更简易。它被期望用来使得类的用户的工作更简易:   
int main() 

 array a; 
 a[3] = 4; // 用户代码应该明显而且易懂... 

  记住:在一个面向重用的世界中,使用你的类的人有很多,而建造它的人只有一个(你自己);因此你做任何事都应该照顾多数而不是少数。 
  什么算符能/不能被重载?大多数都可以被重载。c的算符中只有 . 和 ? :(以及sizeof,技术上可以看作一个算符)。c++增加了一些自己的算符,除了::和.*,大多数都可以被重载。 这是一个下标算符的示例(它返回一个引用)。先没有算符重载: 
class array { 
public: 
int& elem(unsigned i) {  if (i > 99) error(); return data[i]; } 
 private: 
 int data[100]; 
}; 
int main() 

 array a; 
 a.elem(10) = 42; 
 a.elem(12) += a.elem(13); 

  现在用算符重载给出同样的逻辑: 
class array { 
public: 
int& operator[] (unsigned i)  {  if (i > 99) error(); return data[i]; } 
 private: 
 int data[100]; 
}; 
int main() 

 array a; 
 a[10] = 42; 
 a[12] += a[13]; 

  我能重载 operator== 以便比较两个 char[] 来进行字符串比较吗?不行:被重载的算符,至少一个操作数必须是用户定义类型(大多数时候是类)。 但即使c++允许,也不要这样做。因为在此处你应该使用类似 std::string的类而不是字符数组,因为数组是有害的。因此无论如何你都不会想那样做的。