关于C++运算符重载和友元的概念
2015-11-16 12:56
537 查看
关于C++运算符重载和友元的概念
首先提供代码如下:
我们在头文件中定义了一个Time类
#pragma once #ifndef TIME_H_ #define TIME_H_ #include "stdafx.h" using namespace std; class Time { private: int hours; int minutes; public: Time(); Time(int h,int m = 0); void AddMin(int m); void AddHr(int h); void Reset(int h = 0, int m = 0); Time operator*(double n) const; void Show() const; }; #endif
Time类的源文件代码如下:
#include "stdafx.h" #include "Time.h" #include <iostream> Time::Time() { hours = minutes = 0; } Time::Time(int h, int m) { hours = h; minutes = m; } void Time::AddMin(int m) { minutes += m; hours += minutes / 60; minutes %= 60; } void Time::AddHr(int h) { hours += h; } void Time::Reset(int h, int m) { hours = h; minutes = m; } Time Time::operator*(double mult) const { Time result; long totalminutes = hours * mult * 60 + minutes * mult; result.hours = totalminutes / 60; result.minutes = totalminutes % 60; return result; } void Time::Show() const { std::cout << hours << "hours," << minutes << "minutes"; }
测试函数(main)代码如下:
#include "stdafx.h" #include "Time.h" #include <iostream> using namespace std; void main() { Time t1(4,35); Time t2(2, 47); Time adjusted; adjusted = t1 * 1.5; adjusted.Show(); cout << endl; }
运算符重载的概念
代码都在上面可以看,所以简单提一下.通过对*运算符的重载,我们可以直接把一个类的对象(adjusted)乘以一个double类型的值
adjusted = t1 * 1.5; adjusted.Show();
问题提出
在前面的Time类实例中,重载的乘法运算符(*)将一个Time值与一个double结合.注意左侧的操作数是调用对象,也就是说,下面的语句
A = B * 2.75;
将被隐式的转换为下面的成员函数调用
A = B.operator(2.75);
那如果我们写成
A = 2.75 * B;可以吗?答案是不行的,因为这种写法不对应于Time的成员函数.
我们想到一个解决方法:非成员函数
Time operator*(double m, Time &t);
但着引发了一个新问题:非成员函数不能直接访问私有数据,至少常规的成员函数不能访问.然而,有一类特殊的非成员函数可以访问类 的私有成员,它们被称为友元函数.
友元函数
我们在友元函数声明放在类声明中,并在原型声明前加上关键字friend
friend void operator<<(ostream & os,const Time &t);
定义如下:
Time operator*(double mult, Time &t) { Time result; long totalminutes = t.hours * mult * 60 + t.minutes * mult; result.hours = totalminutes / 60; result.minutes = totalminutes % 60; return result; }
经过这样定以后我们就可以直接写出
A = 2.75 * B的代码了
对于友元这里有几点需要注意的是
虽然operator运算符函数实在类中声明的,但它并不是类的成员函数,因此不能使用成员运算符来调用(.);
虽然operator运算符不是类成员函数,所以不要使用Time::域名限定符.另外,不要再定义中使用关键字friend.
重载<<运算符
假设trip是一个Time对象.为了显示Time的值,我们会用Show(),然而,我们如果像下面这样操作会更好:
cout << trip;
我们可以用ostream类来重新重载operator<<()定义
1.<<的第一个重载版本:
要是Time类使用cout,必须使用友元函数,我们可以现在Time类的头文件中声明友元函数friend void operator<<(ostream & os,const Time &t);
在Time类的源文件中定义右元函数
void operator<<(ostream & os,const Time &t) { os << t.hours << "hours," << t.minutes << " }
这样就可以不用调用对象的Show()函数,而是直接输入代码
cout<<adjustde<<endl;
通过对<<的重载就可以直接显示我们要的东西,而不需要调用函数了.
问题提出
以上实现不允许像通常那样重新定义的<<运算符与cout一起使用:
cout << "Trip Time:" << trip << "(TuesDay)\n";
那这时我们该怎么办?
2.<<的第一个重载版本:
我们可以对友元函数采用相同方法,只要修改operator<<()函数,让它返回ostream对象的引用即可friend ostream & operator<<(ostream & os, const Time & t);
ostream & operator<<(ostream& os, const Time &t) { os << t.hours << "hours," << t.minutes << "minutes"; return os; }
用过这样的方法我们就可以正确的使用代码
cout << "Trip Time:" << trip << "(TuesDay)\n";
相关文章推荐
- gcc编译C++程序
- 怎样计算一个整数的位数&并把每一位上的数字保存下来
- C语言总结(一):
- C语言学习笔记(16) c语言字符串分析
- 编写一个程序,要求用户输入最多10个高尔夫成绩,并将其存储在一个数组中。 程序允许用户提早结束输入,并在一行上显示所有成绩,然后报告平均成绩。 请使用3个数组处理函数来分别进行输入、显示和计算
- 虚函数、纯虚函数通俗解释(C++,Java)
- libc++abi.dylib: terminate_handler unexpectedly threw an exception错误小结
- C++基础::STL中的定理
- 将不规则四边形图像插值成为一个矩形图像
- 深入理解C++异常
- C语言用分别用递归和循环求数字的阶乘的方法
- 【C语言】 冒泡排序子例
- 《Effective C++》Rule 18: 让接口容易被正确使用,不易被误用
- C++学习第四课—串
- 【C语言】 冒泡排序
- C++基础::非类型模板参数在STL中的应用
- 切忌在类的初始化列表中调用类的成员函数
- C++88个注意点之1~5
- 关于数据类型与指针的小笔记--初始化问题&&数组
- C++ 动态特性