《C++ primer plus》精炼(OOP部分)——对象和类(3)

学习是人类的天性,持续学习是人类的本能。

抽象数据类型(ADT)

类的思想很适合用来实现抽象数据类型,这进一步增进了代码重用的可能性。
例如,可以用类的思想实现栈。栈由一组相同类型的元素组成,操作包括初始化空栈,push元素,pop元素,查看栈是否为满,查看栈是否为空。
为了提高数据的安全性和代码重用,我们可以适当隐蔽掉一些信息。下面是Stack抽象数据类型的初步声明:

#ifndef STACK_H_
#define STACK_H_

typedef unsigned long Item;//使用Item作为实际存储类型的代称

class Stack
{
private:
	enum { MAX = 10 };//类作用域的常量,由所有对象共享
	Item items[MAX];//使用数组来作为栈的实际存储方式
	int top;
public:
	Stack();
	bool isempty()const;
	bool isfull()const;
	//push() returns false if stack already is full,true otherwise
	bool push(const Item& item);//add item to stack
	//pop() returns false if stack already is empty,true otherwise
	bool pop(Item& item);//pop top into item
};

#endif

声明中有两点需要特别注意:

  1. 使用了typedef语句将实际存储类型unsigned long包装成Item,提高了代码重用性,将来如果想要用double类型的栈,只需要改动typedef语句即可。
  2. 将Item数组设计为私有 这意味着客户看不到栈实际存储的方式,公共接口以数组的形式使用栈中的元素。这意味着我们可以使用其他具有数组性质的存储结构来代替数组,比如vector(可变数组)来扩展功能。

--------------------------第11章:使用类--------------------------

这一章中我们深入类的细节实现,阐释一些便于实现类功能的语法。

运算符重载

我们在基础数据类型的内部实现中已经定义了一些常见的运算符,比如对于两个int类型的数a,b,a+b代表调用+运算符,输出结果为a和b相加。那么,如果我们定义一个Student类,类中带有学生的名字和分数:

class Student{
	string name;
	int grade;
}

我们能不能为这个类定义一个+运算符呢?如果定义的话,这
个运算符的输出结果是简单的“Student+Student”吗?
这显然是不可能的,Student+Student没有任何意义,但如果将+运算符的输出结果定义为Student.grade+Student.grade,这样的运算就有意义了,要实现这样的操作,可以使用运算符重载。
重载,就是重新定义一个函数。我们可以在函数声明和定义中重新定义一个名为“+”的函数。语法如下:

operatorop(argument list](op代表运算符)

那么,我们可以为Student类重载+运算符:

class Student{
	string name;
	int grade;
	int operator+(Student s)//像普通函数一样编写运算符重载,有返回值,只是函数名需要进行指定,由于+运算符是二元运算符,因此需要再传入一个参数
	{
		return this->grade+s.grade;
	}
	int operator+(int a)//可以多次重载同一个运算符,要求传入参数不同,就像普通的重载机制一样
	{
		return this->grade+a;
	}
	int operator+(double b)
	{
		return this->grade-b;//当然也可以这样做,但是这种“以减为加”的行为会混淆运算符的意义,强烈不建议这么做
}

在进行运算符重载的声明和定义后,我们可以使用这个函数:

void test(Student a,Student b)
{
	a.operator+(b);//可以像普通函数那样使用运算符重载函数
	int c=a+b;//这是运算符重载函数的简化使用方式,也是我们一般使用的方式,正如我们所说,实际上a调用了Student类的以Studnet对象b为参数的+运算符重载函数,并把输出结果放入c中
	int d=a+c;//a调用以int类型c为参数的+运算符重载函数并把结果放入d
}

运算符重载限制

C++在语法层面对运算符重载做出了一些硬性规定:

  1. 重载后的运算符必须至少有一个操作数是用户定义的类型
  2. 重载不能违反运算符原来的句法规则。例如,不能把二元运算符(比如+)重载成只有一个操作数:
int operator+()//不会通过编译,因为只有调用这个函数的Student对象一个操作数
{
	return this->grade;
}

也不能修改运算符的优先级(一般也不会修改)

  1. 不能创建新运算符(毕竟是重载)

  2. 不能重载一些特定的运算符:
    在这里插入图片描述
    (一般情况下也不会有人想到重载这些运算符吧)

  3. 有几个运算符只能通过类成员函数进行重载:
    在这里插入图片描述
    (经验:尽量用成员函数重载运算符就好)
    请添加图片描述
    我是霜_哀,在算法之路上努力前行的一位萌新,感谢你的阅读!如果觉得好的话,可以关注一下,我会在将来带来更多更全面的知识讲解!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

霜_哀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值