C++:类————运算符重载、友元函数
2015-02-04 10:36
211 查看
一、运算符重载
>1.什么是运算符重载:
类似于函数重载,运算符重载是C++多态的一种形式,允许程序员一些运算符用于自己制定的数据类型。
>2.为什么要进行运算符的重载:
举一个简单的例子,加入说要将两个数组想加,通常如下:
>3.运算符重载的语法:
统一的格式如下:
一般来说,都是在类的成员函数中声明,在另一个文件中进行定义(和普通的成员函数的定义方式完全相同)。
其实,可以将operator sign整体看做一个函数名,只是它的结合方式不同而已。
例如定义了一个名为Time的Class,t1,t2,t3都是Class的对象,对加法进行了如下重载:
在这里需要强调的是,成员符号".“操作符的结合方式总是自左向右的,如果写t3 = t2 + t1,虽然结果相同,但是实际上是这样调用的 t3 = t2.operator + (t1),此处十分重要。
>4.运算符重载的注意事项:
重载后的运算符必须至少有一个操作数是用户自定义型的,这将防止用户重载标准运算符。
使用运算符不可以违背原来的句法规则,例如%是对两个操作数使用的,不可以出现形如%x的重载
不可以修改运算符的算数优先级
不可以通过重载创建新的运算符
可以通过成员函数(在类内部)或者非成员函数(和普通函数一样,在类的外部)重载,但是有一些运算符"=,(),[],->"只能在成员函数里进行重载
二、友元函数
>1.什么是友元函数
通过让函数称为类的友元,可以赋予该函数同成员函数一样的权限去访问类的私有成员。
>2.为什么要使用友元函数
这里需要举一个直观的例子:
A = B + 50.0(其中A、B是同一种类的对象),这里我们假设对+进行了重载,那么该语句相当于:
A = B.operator + (50.0) (再次强调运算符左侧的操作数是调用对象)
按照运算符左侧是调用对象的规则,A = 50.0 + B 是错误的,因为50.0不是一个对象,这就让我们有点不开心了。
解决访问有两个:一是强制要求大家都写成A = B + 50.0 的形式,这大家肯定非常不开心;二是将重载定义为成非成员函数的形式(即相当于一个普通的函数),非成员函数 的重载的调用规则是将 A = 50.0 + B 与 A = operator + (50.0,B)的等价,这样可以。
但是非成员函数有一个非常大的缺点,不可以访问对象的私有成员,怎么办呢?这时候就由友元函数出马了。
>3.创建友元函数
创建友元函数的第一步是将其原型放在类的声明中,并在声明的前边加关键字friend
第二步就是编写定义,由于友元函数不是成员函数,所以定义中不需要加限定符,这个例子中意思是无需写 Time::,所以定义应该如下:
最为常用的友元函数应该就是operator << ()了,对<<进行重载大大方便了编写输出时的代码。
因为参数按照从左往右的顺序填入,这样语句cout << time 就相当于 operator + (cout,time)
其中os是cout的一个引用,可以使用这种方式。
这里需要说明的是,operator<<()直接访问Time类的私有成员但是不访问ostream类的私有成员,因此它是类Time的友元而不是ostream的友元。
但是这个版本实际上和我们常用的有很大差别,因为不能够 cout << time1 << time2 <<...这样写,实际上我们都知道 cout << time1会返回一个ostream类的对象,才能够继
续使用<<这个符号,因此,我们应当对上述代码改进一下:
>1.什么是运算符重载:
类似于函数重载,运算符重载是C++多态的一种形式,允许程序员一些运算符用于自己制定的数据类型。
>2.为什么要进行运算符的重载:
举一个简单的例子,加入说要将两个数组想加,通常如下:
for(int i = 0 ; i < array_size ; ++i){ c[i] = a[i] + b[i]; }但是借由对“+”运算符的重载,可以直接这样写:
c = a + b;十分方便也更加直观,强调加法的实质而忽略其内部的详细操作,这是OOP的目标之一。
>3.运算符重载的语法:
统一的格式如下:
operator sign (argument_list)其中sign表示某一种运算符的符号。
一般来说,都是在类的成员函数中声明,在另一个文件中进行定义(和普通的成员函数的定义方式完全相同)。
其实,可以将operator sign整体看做一个函数名,只是它的结合方式不同而已。
例如定义了一个名为Time的Class,t1,t2,t3都是Class的对象,对加法进行了如下重载:
class Time() { private: minutes; hours; public: ... ... Time operator + (const Time & t)const; .... };
Time Time:: operator + (const Time & t) const { Time sum; sum.minutes = minutes + t.minutes; sum.hours = hours + t.hours + sum.minutes / 60; sum.minutes %= 60; }那么语句t3 = t1 + t2就相当于t3 = t1.operator + (t2)
在这里需要强调的是,成员符号".“操作符的结合方式总是自左向右的,如果写t3 = t2 + t1,虽然结果相同,但是实际上是这样调用的 t3 = t2.operator + (t1),此处十分重要。
>4.运算符重载的注意事项:
重载后的运算符必须至少有一个操作数是用户自定义型的,这将防止用户重载标准运算符。
使用运算符不可以违背原来的句法规则,例如%是对两个操作数使用的,不可以出现形如%x的重载
不可以修改运算符的算数优先级
不可以通过重载创建新的运算符
可以通过成员函数(在类内部)或者非成员函数(和普通函数一样,在类的外部)重载,但是有一些运算符"=,(),[],->"只能在成员函数里进行重载
二、友元函数
>1.什么是友元函数
通过让函数称为类的友元,可以赋予该函数同成员函数一样的权限去访问类的私有成员。
>2.为什么要使用友元函数
这里需要举一个直观的例子:
A = B + 50.0(其中A、B是同一种类的对象),这里我们假设对+进行了重载,那么该语句相当于:
A = B.operator + (50.0) (再次强调运算符左侧的操作数是调用对象)
按照运算符左侧是调用对象的规则,A = 50.0 + B 是错误的,因为50.0不是一个对象,这就让我们有点不开心了。
解决访问有两个:一是强制要求大家都写成A = B + 50.0 的形式,这大家肯定非常不开心;二是将重载定义为成非成员函数的形式(即相当于一个普通的函数),非成员函数 的重载的调用规则是将 A = 50.0 + B 与 A = operator + (50.0,B)的等价,这样可以。
但是非成员函数有一个非常大的缺点,不可以访问对象的私有成员,怎么办呢?这时候就由友元函数出马了。
>3.创建友元函数
创建友元函数的第一步是将其原型放在类的声明中,并在声明的前边加关键字friend
friend Time operator + (double m,const Time & t);这个原型意味着虽然函数operator + ()是在类中声明的,但是它不能被成员运算符来调用,但是享有和成员函数一样的权利,访问TIme类的私有成员。
第二步就是编写定义,由于友元函数不是成员函数,所以定义中不需要加限定符,这个例子中意思是无需写 Time::,所以定义应该如下:
Time operator + (double m,const Time & t){ ....... }>4.常用的友元函数
最为常用的友元函数应该就是operator << ()了,对<<进行重载大大方便了编写输出时的代码。
void operator << ( ostream & os,const Time & t){ os << t.hours << " hours " << t.minutes << " minutes " << endl; }
因为参数按照从左往右的顺序填入,这样语句cout << time 就相当于 operator + (cout,time)
其中os是cout的一个引用,可以使用这种方式。
这里需要说明的是,operator<<()直接访问Time类的私有成员但是不访问ostream类的私有成员,因此它是类Time的友元而不是ostream的友元。
但是这个版本实际上和我们常用的有很大差别,因为不能够 cout << time1 << time2 <<...这样写,实际上我们都知道 cout << time1会返回一个ostream类的对象,才能够继
续使用<<这个符号,因此,我们应当对上述代码改进一下:
ostream & operator << (ostream & os,const Time & t){ os << t.hours << " hours " << t.minutes << " minutes " << endl; return os; }
相关文章推荐
- 队列(queue) 之 c++模板(友元函数和运算符重载)
- 【c++】关于类继承运算符重载友元函数
- 《C++第八周实验报告1-1(2)》----复数类中的运算符重载,用类的友元函数
- C++抽象编程——面向对象(4)——运算符重载与友元函数
- C++ 友元函数和非成员运算符重载
- 从零开始学C++之运算符重载(一):以成员函数方式重载、以友元函数方式重载
- C++Primer Plus 第十一章-运算符重载和友元函数
- 从零开始学C++之运算符重载(一):以成员函数方式重载、以友元函数方式重载
- 从零开始学C++之运算符重载(一):以成员函数方式重载、以友元函数方式重载
- C++走向远洋——49(项目一2、复数类中的运算符重载、类的友元函数)
- C++学习之路—运算符重载(二)运算符重载作为类的成员函数和友元函数
- C++友元函数以及运算符重载
- c++ 运算符重载 友元函数
- 从零开始学C++之运算符重载(一):以成员函数方式重载、以友元函数方式重载
- C++ 运算符重载与友元函数的简单运用实例
- c++友元函数及运算符重载
- 《C++第八周实验报告1-1(2)》----复数类中的运算符重载,用类的友元函数
- 队列(queue) 之 c++模板实现(友元函数和运算符重载)
- C++: 运算符重载(一)、友元函数、链式编程支持
- C++实现输入输出运算符重载、友元函数和成员函数实现复数类Complex