学习是人类的天性,持续学习是人类的本能。
文章目录
- 抽象数据类型(ADT)
- --------------------------第11章:使用类--------------------------
- 运算符重载
- 运算符重载限制
抽象数据类型(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
声明中有两点需要特别注意:
- 使用了typedef语句将实际存储类型unsigned long包装成Item,提高了代码重用性,将来如果想要用double类型的栈,只需要改动typedef语句即可。
- 将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++在语法层面对运算符重载做出了一些硬性规定:
- 重载后的运算符必须至少有一个操作数是用户定义的类型
- 重载不能违反运算符原来的句法规则。例如,不能把二元运算符(比如+)重载成只有一个操作数:
int operator+()//不会通过编译,因为只有调用这个函数的Student对象一个操作数
{
return this->grade;
}
也不能修改运算符的优先级(一般也不会修改)
-
不能创建新运算符(毕竟是重载)
-
不能重载一些特定的运算符:
(一般情况下也不会有人想到重载这些运算符吧) -
有几个运算符只能通过类成员函数进行重载:
(经验:尽量用成员函数重载运算符就好)
我是霜_哀,在算法之路上努力前行的一位萌新,感谢你的阅读!如果觉得好的话,可以关注一下,我会在将来带来更多更全面的知识讲解!