第十一章 使用类(1)

前面一章终于学习了类,但类博大精深,一章基本也就知道了怎么定义使用最简单的类。这一章就稍微深入探讨一下类之所以强大的许多特性。


1. 运算符重载

运算符重载是一种形式的多态,它允许赋予C++运算符多种含义。比如我们想做这样的加法evening = sam + janet ,这三个都是三个对象,这时候我们就要对加号重载。

运算符函数的格式如下

operatorop(argument-list)

这里op就是各种C++支持的运算符(加减乘除啥的呢)

书中举了一个计算时间的例子,把两个几小时几分的对象相加,这个对象属于Time class,包括hours和minutes的private数据成员还有其他一系列方法成员

class Time

{

private:

int hours;

int minutes;

public

Time operator+(const Time & t) const;

...

}

上面的operator+就是这个加号运算符重载函数的原型,下面是函数定义

Time Time::operator+(const Time & t) const

{

Time sum;

sum.minutes = minutes + t.minutes;

sum.hours = hours + sum.minutes/60;

sum.minutes %= 60;

return sum;

}

这一看跟普通的sum函数一模一样么,但用起来就很简单了

Time t1, t2, t3;

t1 = ...; t2 = ...;

t3 = t2 + t1; 

可以直接用加号把两个Time对象相加了,并返回正确的time

其实t3 = t2 + t1对编译器来说是这样的t3 = t2.operator+(t1);

其实如果有t4的话,t4 = t3 + t2 + t1这样也是可以的


重载也有些限制:

重载后的运算符必须至少有一个操作数是用户定义的类型,这将防止用户为标准类型重载运算符。

使用运算符是不能违反运算符原来的句法规则,也不能修改运算符的优先级。

不能创建新的运算符

不能重载下面的运算符: sizeof sizeof运算符; . 成员运算符;

.* 成员指针运算符;:: 作用域解析运算符

等等等等

大多数运算符都可以通过成员或非成员函数进行重载,但下面的运算符只能通过成员函数进行重载:

= 赋值运算符

() 函数调用运算符

[] 下标运算符

-> 通过指针访问类成员的运算符


2. 友元

类经常会有标记为private的私有成员,之所以放在private下面,就是不想让外面访问。可c++又开了一个后门,即另外一种形式的访问权限:友元。

友元有3种: 友元函数,友元类,友元成员函数。这里只介绍友元函数

书里面举了一个重载乘法运算符的例子,如果A和B是同一个类的两个对象,这个类包含一个重载乘法运算符的方法,那么一般可以这样A = B*2,但如果要写A = 2*B的话,还需要定义一个新的函数,可以在类外面定义一个非成员的乘法运算符重载函数。如果要让这个非成员函数也要访问类私有变量的话,就得把它标记为类的友元函数。例如书中的例子:

friend Time operator*(double m, const Time & t);

这就表明这个operator*是Time的友元,可以访问Time类t对象的私有成员

注意不要在函数定义时再写关键字friend


一个经常用的友元的例子就是对<<运算符的重载。还是举Time类的例子,现在有一个trip的对象,我们想通过

cout << trip; 来显示trip是几时几分。

cout其实是ostream类的一个对象。如果使用一个Time成员函数来重载<<,Time对象将是第一个操作数,结果就是trip << cout。 所以我们必须使用一个非成员函数来重载<<,这个非成员函数还必须是Time类的friend,才能访问Time类的所有私有成员。这个函数可以这样定义

void operator << (ostream & os, const Time & t)

{ os << t.hours << " hours, " << t.minutes << " minutes"; }

但这个是不能这样

cout << "Trip time : " << trip << " (Tuesday)\n";

如果这样必须要重载函数返回一个ostream的对象

ostream & operator<< (ostream & os, const Time & t)

 {

os << t.hours << " hours, " << t.minutes << " minutes"; 

return os;}


之后本章举了一个很大的vector的例子来详细说明了类的基本使用,运算符重载,友元函数,自己敲一边基本就明白啦。组合函数实现用了一个醉鬼走路的例子,还是很有意思的


3. 类的自动转换和强制类型转换

这一小节就是将类和普通类型的转换。

比如可以通过构造函数来讲一个普通类型的变量赋给一个类的对象

也可以将一个类的对象赋给一个普通类型的变量,这个时候就要在类里面额外添加一个转换函数了。要注意到是;

转换函数必须是类方法

转换函数不能指定返回类型

转换函数不能有参数,

例如转换为double类型的函数的原型如下:operator double();

调用是赋值符合=的左边之间放对象的名字就行。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值