1运算符重载的规则
C++ 几乎可以重载全部的运算符,而且只能够重载C++中已经有的。
不能重载的运算符:“.”、“.*”、“::”、“?:”
重载之后运算符的优先级和结合性都不会改变。
重载的两种形式:
1 重载为类的非静态成员函数;
2 重载为非成员函数。
2双目运算符重载为成员函数
函数类型 operator 运算符(形参)
{
......
}
参数个数=原操作数个数-1 (后置++、--除外)
双目运算符重载规则:
如果要重载 B 为类成员函数,使之能够实现表达式 oprd1 B oprd2,其中 oprd1 为A 类对象,则 B 应被重载为 A 类的成员函数,
形参类型应该是 oprd2 所属的类型。
经重载后,表达式 oprd1 B oprd2 相当于 oprd1.operator B(oprd2)
//例8-1复数类加减法运算重载为成员函数 #include<iostream> using namespace std; class Complex{ public: Complex(double r = 0.0, double i = 0.0):real(r), image(i){} Complex operator +(const Complex &c2) const; Complex operator -(const Complex &c2) const; void display() const; private: double real; double image; }; Complex Complex::operator+(const Complex &c2) const{ return Complex(real+c2.real, image+c2.image);//创建一个临时无名对象作为返回值 } Complex Complex::operator-(const Complex &c2) const{ return Complex(real-c2.real, image-c2.image); } void Complex::display() const{ cout << "(" << real << ", " << image << ")" << endl; } int main(){ Complex c1(5,4),c2(2,10),c3; cout << "c1 = "; c1.display(); cout << "c2 = "; c2.display(); c3 = c1 - c2; cout << "c3 = c1 - c2 = "; c3.display(); c3 = c1 + c2; cout << "c3 = c1 + c2 = "; c3.display(); return 0; }
3单目运算符重载为成员函数
前置单目运算符重载规则:
如果要重载 U 为类成员函数,使之能够实现表达式 U oprd,其中 oprd 为A类对象,则 U 应被重载为 A 类的成员函数,无形参。
经重载后,表达式 U oprd 相当于 oprd.operator U()
后置单目运算符 ++和--重载规则:
如果要重载 ++或--为类成员函数,使之能够实现表达式 oprd++ 或 oprd-- ,其中 oprd 为A类对象,则 ++或-- 应被重载为 A 类的成员函数,且具有一个 int 类型形参。
经重载后,表达式 oprd++ 相当于 oprd.operator ++(0)
//例8-2重载前置++和后置++为时钟类成员函数 #include<iostream> using namespace std; class Clock{ public: Clock(int hour = 0, int minute = 0, int second = 0); void showTime() const; Clock& operator ++();//前置单目运算符重载 Clock operator ++ (int);//用参数表来区分两个重载函数,函数体中不适用 private: int hour, minute, second; }; Clock::Clock(int hour, int minute, int second){ if(0 <= hour && hour < 24 && 0 <= minute && minute < 60 && 0 <= second && second <60){ this->hour = hour; this->minute = minute; this->second = second; }else{ cout << "Time error!" << endl; } } void Clock::showTime() const{ cout << hour << " : " << minute << " : " << second << endl; } Clock &Clock::operator ++ (){//返回本类对象的引用 second++; if(second >= 60){ second-=60; minute++; if(minute >= 60){ minute-=60; hour = (hour+1)%24; } } return *this; } Clock Clock::operator ++(int){ Clock old = *this; ++(*this);//调用前置++运算符(形参) return old; } int main(){ Clock myClock(23,59,59); cout << "First time output: "; myClock.showTime(); cout << "Show myClock++: "; (myClock++).showTime(); cout << "Show ++myClock: "; (++myClock).showTime(); return 0; }
4运算符重载为非成员函数
运算符重载为非成员函数的规则:
函数的形参代表依自左至右次序排列的各操作数。
参数个数=原操作数个数(后置++、--除外)
至少应该有一个自定义类型的参数。
如果在运算符的重载函数中需要操作某类对象的私有成员,可以将此函数声明为该类的友元。
双目运算符 B重载后,
表达式oprd1 B oprd2
等同于operator B(oprd1,oprd2)
前置单目运算符 B重载后,
表达式 B oprd
等同于operator B(oprd )
后置单目运算符 ++和--重载后,
表达式 oprd B
等同于operator B(oprd,0)
//例8-3 重载Complex的加减法和“<<”运算符为非成员函数 #include<iostream> using namespace std; class Complex{ public: Complex(double r = 0.0, double i = 0.0):real(r), image(i){} friend Complex operator+(const Complex &c1, const Complex &c2); friend Complex operator-(const Complex &c1, const Complex &c2); //它的左操作数是std::ostream引用,右操作数为复数类的常引用,返回std::ostream引用 friend ostream &operator<<(ostream &out, const Complex &c); private: double real; double image; }; Complex operator+(const Complex &c1, const Complex &c2){ return Complex(c1.real+c2.real, c1.image+c2.image); } Complex operator-(const Complex &c1, const Complex &c2){ return Complex(c1.real-c2.real, c1.image-c2.image); } ostream &operator<<(ostream &out, const Complex &c){ out << "(" << c.real << ", " << c.image << ")"; return out; } int main(){ Complex c1(5,4),c2(2,10),c3; cout << "c1 = " << c1 << endl; cout << "c2 = " << c2 << endl; c3 = c1 - c2; cout << "c3 = c1 - c2 = " << c3 << endl; c3 = c1 + c2; cout << "c3 = c1 + c2 = " << c3 << endl; return 0; }