-
多态
- 同一种类型的不同表现形式
- 基类指针指向基类对象基类对象调用的成员函数,基类指针指向派生类对象则调用派生类得成员函数,这种现象就称为多态
- 构成多态的条件
- 继承关系
- 基类多态函数必须声明为虚函数(virtual)
- 派生类必须覆盖(重写)基类的虚函数
- 基类指针指向对象(基类、派生类)
- 如果一个功能接口需要通过不同的对象有不同的表现形式,使用多态来实现
- 实现多态可以用基类指针,或者是基类的引用,使用基类对象是不能实现多态的
-
纯虚函数
- virtual void func() = 0;
- 没有实现的
- 约定接口,派生类需要实现这个接口
- 包含纯虚函数的类叫做纯虚类,纯虚类不能被实例化
- 举例
- 线类、矩形类、长方体类、正方体类
- 线类:长度,没有面积和体积的,可以用于限定派生类必须实现面体和体积函数,那么线类就可以将面积,体积声明为纯虚函数
-
运算符的重载
- 运算的重载本质上就是函数的重载,函数名:operator
-
有两种方式:
- 全局函数,声明为类的友元(friend)(多用于双目运算符)
- friend TYPE operator ?(TYPE &,TYPE &);
- 类的成员函数(多用于单目运算符)
- TYPE operator ?(TYPE &)
- 全局函数,声明为类的友元(friend)(多用于双目运算符)
- 对象在做运算的时候,编译器会自动调用operator运算符
- 不可被派生类继承
-
重载运算符的规则
- 遵循运算符本身功能
- 不能改变优先级
- . .* sizeof ?: :: 不支持重载
- >> << 只能做为全局函数重载
- = [ ] ( ) -> 只能做为类的成员函数重载
- ++ --前置后置重载区分
- operator++ ( ) 前置
- operator++ ( int n)后置 n没有任何含义的,仅仅为了区分
- [ ]下标运算符 只读 \ 修改
- const type &operator[ ] () const ; 只读
- type &operator[ ] () ; 修改
- 注意:知道函数功能,才能正确规定函数返回值
-
练习01
- 定义一个复数类,有实部和虚部,要求支持+-运算,尝试支持++ --运算,还要支持cin读入cout输出 灵活运用this指针
- 定义字符串类, 支持字符串+,加法运算就是字符串的拼接,支持=运算,就是字符串的复制,支持==运算,就是字符串的比较(注意深拷贝)支持cin读入cout输出
- 温故而知新。。。
-
模版template
- 为了实现泛型编程,一个函数或者一个类对于参数或者是成员类型,可以实现通用类型
- 函数模版
- template <typename T> void func(T a); T - - - > TYPE
- T类型就是通用的,在调用时根据传参类型决定函数的传参类型
- 类模板
- template <typename T , typename T2 ...> class Test { };
- 类模板的成员函数在类外定义
- 一定要带模版头 template <typename T1, typename T2 ....>
- 一般函数的声明和定义都写在 .h文件中
-
模版中友元函数的声明
- 前置声明,声明类和友元函数
-
练习02
- 实现动态数组类,要求适应任意类型,支持基本运算,例如 [ ] = <<
- 实现一个模板栈类,Stack栈中可以容纳任意类型的元素,栈是有上限,提供基本功能,例如栈空,栈满,入栈,出栈,获取栈顶元素