C++学习笔记-操作符重载
2014-11-09 18:58
162 查看
操作符重载(operator overloading)是一种形式的C++多态,C++将操作符重载扩展到用户自定义的类型,如允许使用+将两个自定义的对象相加,编译器将根据操作数的数目和类型决定使用那种加法定义。
要重载操作符,需使用操作符函数,格式如下:
operator op (argument-list)
op:要重载的操作符
argument-list: 操作数
操作符函数可以是类的成员函数,也可以是友元函数,如果是类成员函数,则第一个操作数是调用对象,它不在argument-list中。
操作符重载范例,定义一个时间类Time,重载 + - *操作符。
//Time.h
//具体实现 Time.cpp
View Code
要重载操作符,需使用操作符函数,格式如下:
operator op (argument-list)
op:要重载的操作符
argument-list: 操作数
操作符函数可以是类的成员函数,也可以是友元函数,如果是类成员函数,则第一个操作数是调用对象,它不在argument-list中。
操作符重载范例,定义一个时间类Time,重载 + - *操作符。
//Time.h
#ifndef TIME_H_ #define TIME_H_ #include <iostream> class Time { public: Time(void); Time(int h,int m = 0); ~Time(void); void AddMin(int m); void AddHr(int h); void Reset(int h = 0, int m = 0); void Show()const; //重载 +操作符 Time operator+ (const Time & t)const; Time operator- (const Time & t)const; // * Time operator* (double n) const; //友元函数 friend Time operator* (double n, const Time & t); //重载<<操作符 friend std::ostream & operator<< (std::ostream & os, const Time & t); private: int m_hours; int m_minutes; }; #endif
//具体实现 Time.cpp
#include "Time.h" Time::Time(void) :m_hours(0) ,m_minutes(0) { } Time::Time(int h,int m) :m_hours(h) ,m_minutes(m) { } Time::~Time(void) { } void Time:: AddMin(int m) { m_minutes += m; m_hours += m_minutes / 60; m_minutes = m_minutes % 60; } void Time::AddHr(int h) { m_hours += h; } void Time::Reset(int h, int m) { m_hours = h; m_minutes = m; } void Time::Show()const { std::cout << m_hours << ":" << m_minutes; } Time Time::operator+ (const Time & t)const { Time sum; sum.m_minutes = m_minutes + t.m_minutes; sum.m_hours = m_hours + t.m_hours + sum.m_minutes / 60; sum.m_minutes = sum.m_minutes % 60; return sum; } Time Time::operator- (const Time & t)const { Time diff; int total1,total2; total1 = m_minutes + m_hours * 60; total2 = t.m_minutes + t.m_hours * 60; diff.m_hours = (total1 - total2) / 60; diff.m_minutes = (total1 - total2) % 60; return diff; } Time Time::operator* (double n) const { Time result; long total_minutes = m_hours * 60 * n + m_minutes * n; result.m_hours = total_minutes / 60; result.m_minutes = total_minutes % 60; return result; } Time operator* (double n, const Time & t) { Time result; long total_minutes = t.m_hours * 60 * n + t.m_minutes * n; result.m_hours = total_minutes / 60; result.m_minutes = total_minutes % 60; return result; } std::ostream & operator<< (std::ostream & os, const Time & t) { os << t.m_hours << ":" << t.m_minutes; return os; }
View Code
Time operator- (const Time & t)const; 重载减法操作符后,可以很方便对Time对象进行减法运算 Time start_time(10,40); Time end_time(11,50); Time diff_time = end_time - start_time; 操作符函数为成员函数时,操作符左侧的对象是调用对象,右侧的为参数传递的对象,如上述减法操作实际上等同于: end_time.operator-(start_time); 关于操作符重载: 1、重载限制 1)重载后的操作符必须至少有一个操作数是自定义类型,主要是防止用户为标准类型重载操作符。 2)使用操作符不能违反操作符原来的句法规则。如 % 是二元操作符,需要两个操作数,不能将它重载成使用一个操作数。 3)不能修改操作符的优先级 4)不能定义新的操作符 5)以下操作符不能重载: sizeof . .* --成员指针操作符 :: ?: --条件运算符 typeid --一个RTTI操作符 const_cast --强制类型转换符 dynamic_cast reinterpret_cast static_cast 6)大部分操作符都可以通过成员函数或非成员函数进行重载,但下面的操作符只能通过成员函数重载: = 赋值操作符 () 函数调用操作符 [] 下标操作符 -> 通过指针访问类成员的操作符 2、通过友元函数重载 对于很多操作符来说,可以选择使用成员函数或非成员函数来实现操作符重载。一般来说非成员函数应该是友元函数,这样才可能直接访问类的私有数据。 如对于Time类的加法操作符: 使用类成员函数重载 Time operator+ (const Time & t)const; 使用非成员函数重载: friend Time operator+ (const Time & t1, const Time & t2); 对于成员函数版本,一个操作数通过this指针隐式传递,一个通过参数表 友元版本,两个操作数都作为参数来传递 这两种重载方式都能匹配 T1+T2 但在重载操作符中,只能选择其中的一种格式,同时定义被视为二义性错误,导致编译错误。 有些情况必须使用友元来重载 在Time类中,*乘法操作符与其他两种重载的操作符不同,它使用了两种不同的类型,将一个Time值与一个double值结合在一起,这限制了该操作符的使用方式 *使用成员函数重载如下: Time operator* (double n) const; 意味着只能这样使用该操作符 A = B * 2.5 --> A = B.operator*(2.5) (注:左侧操作数应是调用对象) 如果这样使用将导致编译错误 A = 2.5 * B (左侧操作数是调用对象,而2.5不是对象) 这种情况可以用非成员函数来解决,由于要访问私有数据,故定义为友元函数: friend Time operator* (double n, const Time & t); 此时,A = 2.5 * B --> A = operator*(2.5,B) 对于非成员重载操作符函数,op左边的操作数对应第一个参数,op右边的操作数对应第二个参数。 创建友元: a、友元函数的原型应放在类声明中,并加上friend关键字 friend Time operator* (double n, const Time & t); operator*在类中声明,但不是类的成员函数,但与成员函数具有相同的访问权限 b、在cpp文件中定义函数,由于不是成员函数,故不使用::限定符,也不要在定义中使用friend关键字 总结:类的友元函数是非成员函数,其访问权限与类成员函数相同。 3、常见的友元,重载<<操作符 重载<<操作符,使之能与cout一起来输出对象的内容 原型: friend std::ostream & operator<< (std::ostream & os, const Time & t); 实现如下: std::ostream & operator<< (std::ostream & os, const Time & t) { os << t.m_hours << ":" << t.m_minutes; return os; } 如此以来就可以直接输出Time对象 Time t(10.50) cout << t; 一般来说,要重载<<操作符来显示c_name对象,可使用友元函数,定义如下: ostream & operator<< (ostream & os, const & c_name obj) { os << ....; //输出对象内容 return os; } 之所以要返回ostream的引用,主要作用是可以拼接输出,如 cout << "Current Time:" << t << "\n";
相关文章推荐
- C++基础学习笔记----第十三课(操作符重载-下)
- C++入门学习笔记(三)--类的操作符重载
- c++学习笔记(9.操作符重载)
- C++基础学习笔记----第十三课(操作符重载-下)
- C++学习笔记(七)--操作符重载 友元函数 类的继承 访问控释protected
- C++基础学习笔记----第十二课(操作符重载-上)
- C++学习笔记 操作符重载一
- C++学习笔记:数组的操作符重载(包括[]和=运算符)
- C++学习笔记--数组操作符重载
- C++ ->操作符重载的思考 (Boolan学习笔记第八周)
- C++之操作符重载和友元学习笔记
- C++学习笔记9-操作符重载
- C++拓展笔记3-1:三类操作符重载学习总结
- 操作符重载——C/C++学习笔记
- c++入门学习笔记继承
- c++入门学习笔记--类和对象
- C++学习笔记(5)
- c++学习笔记 2005-9
- c++学习笔记
- 从今天开始每天写C++或其他学习的知识的笔记,以激励自己