纯虚函数
被指明,但不具体实现的虚拟函数
什么是抽象类?
含有纯虚函数的类我们就叫抽象类
由纯虚函数来确定它作为抽象类
下面这种做法,编译不通过
C语言里面有没有抽象类型?
void(无类型) 不能定义实体,不能定义变量
但是void可以定义指针,可以指向任何类型的指针,(泛型指针)
C++中把类的虚方法置为0,作为抽象类
抽象类的应用规则
看下面这例子:
定义一个Shapes抽象类,计算面积
定义一个正方形类公有继承Shapes类
定义一个圆形类公有继承Shapes类
指针的特点是指针可以为空,引用的特点是必须给引用初始化
编写主函数
以引用或者以指针调动其虚函数,产生编译时的多态
抽象类型无法定义对象,但是可以定义指针或者引用
派生类在继承它时,必须要把这个抽象方法实现!
正方形和圆形有着统一的根:Shapes
子类型继承了Shapes类,必须要实现它计算面积的方法(抽象方法)
如果子类没有实现抽象方法,子类型也变向地成为抽象类型
子类型必须实现抽象方法。
抽象类的规定
纯虚函数和虚函数的区别
第一种类型:实例类型(普通类型):可以构建类型
第二种类型:抽象类型:其中的某些方法被定义成纯虚函数
第三种类型:interface,(接口),不定义属性,所有的方法都定义成纯虚函数
interface是什么?
接口(所有类型的底层设计)
要想实例化,必须实现其所有的纯虚方法
动态联编
请问下面这段代码输出的是什么?
输出的是
Base::fun a: 10
在我们创建对象时,先构建Object再构建base对象。op指针指向base的地址。Object类型的op指针,在op->fun();静态联编,确定可访问属性和默认值,公有的,编译可以通过,确定默认值10,我们调用的时候,是动态方案
我们在这里有一个base对象,base对象有隐藏的Object对象,但是虚表的指针指向的是base的虚表,查的是base的fun,没有给200给a,因为编译的时候确定的是10,所以打印Base::fun a: 10
模板的概念
类型重命名,在编译时完成的。
编译时产生两个模板类型,再具体地编译
is和ds是不同的类型,不能相互赋值(编译之后,两者的类型名不一样了)
两者写法
模板类内声明类外定义的写法
还有一种概念
SIZE是非类型,必须是编译时的常量
编译器在编译时
还有一种是给默认值,必须是从右向左给默认值
部分特化,完全特化的概念
上面这个T,只要是类型,放马过来
下面进行部分特化
类型名加()是 构建一个对象
智能指针
什么是裸指针?裸指针存在的问题有什么?
这种写法造成内存泄漏
可以用一个对象进行构造函数的管理,析构函数对对象的撤销
auto_ptr智能指针
比较混乱的,并没有严格意义上的划分
当我们调动fun函数,给了一个智能指针,创建一个对象,调用其构造函数,函数结束,要释放掉这个对象
自己实现 auto_ptr智能指针
当进入主函数,调动fun函数,为fun定义一个栈帧,定义op对象,两个成员:拥有者和_ptr指针。
创建op这个对象调用构造函数,构造之前new一个空间初始化为10,把p给_ptr,函数要结束,调动析构函数,退出来,指针为空,拥有者为假
补充auto_ptr
重载了指向符
两种写法等价
不能这么写!
使其有指针的特性(智能指针)
智能指针,对自己所指的对象自动管理
重置指针
此时的智能指针op和第一个对象没有关系,和第二个对象有关系。
把第一个资源释放掉,指向第二个资源
在auto_ptr中实现重置指针的方法如下
auto_ptr释放拥有权
产生两个对象,析构一个对象
auto_ptr释放拥有权的函数
此写法,编译不通过,常方法下进行不了赋值操作
常方法中,如何操作使得我们可以操作对象的属性?
如何解决?使得在常方法中可以修改value的值
方法1:
易变关键字 mutable
对属性加上这个关键字,在常方法中,这个属性仍然可以被改变,不受const常方法的限制
方法2: 强制转换
把整型value,去除常性
方法3对this指针下手
下面回到我们的主题auto_ptr上
编译还是不能通过,形成了将亡值,不能给将亡值赋值
这个地方是正确的,把ch强转成int类型,构建一个临时量是int类型的,把ch的值给临时量,再把临时量给给c,这个临时量具有常性但是不可以赋值
这个写法是错误的,把ch强转成int类型,构建一个具有int类型的临时量,把100对这个临时量赋值,这是不允许的。
不能给临时量(将亡值)赋值!
正确操作如下:
auto_ptr还有一个函数
交换
auto_ptr智能指针为什么被C11标准舍去呢?
使用场景不明确
为了和boost库抗衡
boost的库的智能指针 有共享型,唯一型,指针池
auto_ptr智能指针意义不明确,构造不明确
拿op1去构造op2,说明这两个对象共享同一套资源。
导致资源会被重复释放!
当op2释放时,op1释放,重复释放了,auto_ptr解决不了
拥有权发生转移
但是如果执行 int x=op1->Value();就出现问题了
转移之后,op1是空指针,从空指针捞值,系统就崩溃了
怎么编怎么不舒服!!!
更危险的操作:
程序运行,我们构建op1对象,有一个拥有权为1,和指针,指针指向Object,为10,当我们调动funobj函数的时候,拿op1对象初始化op2,调动拷贝构造函数进行初始化,op2的拥有权为1,调动release函数,op2的指针指向了Object,并且把op1的指针变为空,op1的拥有权变为0,等到进入funobj函数,调动x,x=10;打印出10,当这个函数调动完成之后,op2要析构掉,把指向的Object对象也析构掉了,回到fun的时候,我们可以看见op1没有拥有权,这个对象已经被提前释放了。
意义不够明确。这里的构造函数没有意义可说
这里的赋值,将要达到什么意义?
auto_ptr的赋值函数
op2拥有的对象被覆盖掉,把op1的对象给给op2,op1 ,op2共同拥有这个对象
赋值意义不明确
还有一个问题
如果
给的是一组对象,但是析构的时候,仍然按照一个对象的来析构
不知道指向的是一组对象还是一个对象
auto_ptr不能和stl中的vector容器愉快地玩耍
所以c11标准中把auto_ptr舍弃掉!