C++自带的运算符,像加减乘除,只支持一些基本的类型,很多时候,我我们需要用运算符实现一些复杂或抽象类型的计算,计算原理或形式虽然符合该计算符,但类型不支持,比如定义一个包含实部跟虚部的复数类,标准C++要实现该类对象的加减乘除运算显然不行,但是我们可以通过C++运算符重载的办法来实现这一功能。
下面就以此例,来抽象出一个复数类,并实现针对该类的加减乘除运算的重载函数。
我们知道,若复数z1=a+bi,z2=c+di,其中a,b,c,d∈R,则
z1±z2=(a+bi)±(c+di)=(a±c)+(b±d)i,
(a+bi)·(c+di)=(ac-bd)+(bc+ad)i,
(a+bi)÷(c+di)=(ac+bd)/(c^2+d^2) +(bc-ad)i/(c^2+d^2)
所以不难得出该类复数抽象出来的类以及复数加减乘除运算符重载如下:
#include <iostream> using namespace std; class Plural { private: double real; //实部 double imag; //虚部 public: void display() { cout << real; if (imag > 0) cout << "+"; cout << imag << 'i' << endl; } Plural() { real = 0; imag = 0; } Plural(double a, double b) { real = a; imag = b; } Plural operator + (const Plural &a) { Plural temp; temp.real = real + a.real; temp.imag = imag + a.imag; return temp; } Plural operator - (const Plural &a) { Plural temp; temp.real = real - a.real; temp.imag = imag - a.imag; return temp; } Plural operator * (const Plural &a) { Plural temp; temp.real = real * a.real - imag * a.imag; temp.imag = imag * a.real + real * a.imag; return temp; } Plural operator / (const Plural &a) { Plural temp; temp.real = (real * a.real + imag * a.imag) / ( a.real * a.real + a.imag * a.imag); temp.imag = (imag * a.real - real * a.imag) / (a.real * a.real + a.imag * a.imag); return temp; } }; int main(void) { Plural a(1, -2); Plural b(-3, 4); Plural c; cout << "a = "; a.display(); cout << "b = "; b.display(); c = a + b; cout << "a + b = "; c.display(); c = a - b; cout << "a - b = "; c.display(); c = a * b; cout << "a * b = "; c.display(); c = a / b; cout << "a / b = "; c.display(); return 0; } 运行结果: a = 1-2i b = -3+4i a + b = -2+2i a - b = 4-6i a * b = 5+10i a / b = -0.44+0.08i
C++编译器把a+b解释为a.operator(b)以后再调用,它返回一个临时变量temp然后赋值给c对象。
1、运算符重载与一般函数重载的区别:
区别主要在参数个数跟是否必须有返回值上。C++运算符所能操作的操作数是约定好了的,在二元运算的时候只能指定两个参数,一元运算的时候只能指定一个参数,而函数重载没有参数个数限制。函数重载对返回值没有限制,可有可无,但是一个运算的结果通常要供别的运算符使用或者能赋值给一个变量或对象,所以必须指定一个非void的返回类型(赋值运算符除外)。
2、友元运算符与类运算符的取舍:
通常情况下,由于友元运算符不要求第一个参数一定要为某个类的对象,故二元运算符重载为一个友元运算符比重载为成员运算符便于使用。一元运算符重载为成员函数最恰当,重载为友元也可以,但增1减1运算符重载为友元运算符时必须使用引用参数。
3、赋值运算符重载:
赋值(=)是二元运算符,赋值运算符重载与拷贝构造函数相似而又不同:它们都必须是类的成员函数而不允许是友元函数,也不能被派生类继承,都有且仅有一个参数;赋值运算符重载函数允许有返回值,而拷贝构造函数以及所有构造函数则不允许。
下面是String类的拷贝构造函数跟赋值重载函数:
String::String(const String &other) { int length = strlen(other.m_data); m_data = new char[length+1]; strcpy(m_data, other.m_data); } //赋值运算符重载函数 String & String::operate =(const String &other) { if(this == &other) return *this; delete [] m_data; int length = strlen( other.m_data ); m_data = new char[length+1]; strcpy( m_data, other.m_data ); return *this; } 或 void String::operate =(const String &other) { if(this == &other) return ; delete [] m_data; int length = strlen( other.m_data ); m_data = new char[length+1]; strcpy( m_data, other.m_data ); }
4、下标运算符重载:
它是一个双目运算符,第一个运算符是数组名,第二个运算符是数组下标,C++不允许将其作为友元函数来定义,它之允许是非静态的成员函数,其一般定义形式如下:
T1 T::operator[](T2);
5、增1减1运算符重载:
对类T的对象a,下表列出其增1和减1运算符重载函数的定义和调用形式:
运算符名 成员函数定义形式 外部函数定义形式 调用形式
前缀++ T operator ++ () T operator ++ (T&) ++a
后缀++ T operator ++ (int) T operator ++ (T&,int) a++
前缀– T operator — () T operator — (T&) –a
后缀– T operator — (int) T operator — (T&,int) a–
6、类型转换运算符重载:
类型转换是c语言中的一个关键特征,c++提供两种方法来自动地处理类型转换。第一种是建立类的构造函数。转换构造函数可以将外来类型转换成类的一个对象。第二中是建立转换运算符重载函数,它可以将一个对象自身的类型转换为其他类型。定义一个转换函数使用关键字operator,后跟要转换的类型的名字。转换函数有以下限制:
(1).转换函数不能带任何参数,并且总是成员函数。
(2).不能说明类型转换函数的返回类型。隐含的返回类型是要转换的类型。在函数体中,适当的值必须返回。转换函数也可以通过显示类型转换表达式被调用,或使用名字直接调用。
除非注明,文章均为CppLive 编程在线原创,转载请注明出处,谢谢。