道歉:前段时间忽略了,我可能比较懒吧(可能周末期来临了,
),我要自我反思,希望大家多多督促我,我们一起向前进步
引子1:as we all known ,在c语言中我们进行不同类型时,要用不同函数名以及不同类型修饰,对此c++先引用了函数重载概念,但是这只是解决不同函数名的问题,所以,c++又引入模板来解决不同类型问题,避免重复写的麻烦!
引子2:当我们想在上一个类中进行扩展以及修改时,我们就要使用继承的知识(叫做基于基类的派生类)!
模板:
模板分为函数模板和类模板
关键字:template<typenme T>
typename是用来定义模板参数关键字,也可以使用class
函数模板
函数模板在使用时被参数化,根据实参类型产生函数的特定类型版本
编译器推演原理:在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供 调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然 后产生一份专门处理double类型的代码,对于字符类型也是如此。如下图的调试:

但是要注意的是:让编译器根据实参推演模板参数的实际类型时,通过实参h1将T推演为int,通过实参h2将T推演为double类型,但模板参数列表中只有一个T, 编译器无法确定此处到底该将T确定为int 或者 double类型而报错!

对此,我们要进行强制转化或使用显式实例化,auto也是可以的
如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错
模板参数的匹配原则 :找最符合自己胃口的进行使用!(能省力就省力!)
1,对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模 板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板
2,模板函数不允许自动类型转换,但普通函数可以进行自动类型转换
类模板
类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<> 中即可,类模板名字不是真正的类,而实例化的结果才是真正的类,注意不同的类型就是一个新的类!
非类型模板参数
其实也很简单就是,在传的时候加一个常量,注意: 1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的。 2. 非类型的模板参数必须在编译期就能确认结果。
用法也很简单:

区别:My_array<int ,10>与int array[10]
越界检查:int array[10]是一种抽查,进行读的时候不会有影响


而My_array<int ,10>是一种严格的检查!只要有调用时越界就会抛异常!
强调点:模板是按需实例化的,不实例化,编译器可能不知道类型不敢,就会报错!
要使用(typename 确定类型!);

模板的特化
模板特化中分为函数模板特化与类模板特化
函数模板特化
函数模板的特化步骤: 1. 必须要先有一个基础的函数模板 2. 关键字template后面接一对空的尖括号<> 3. 函数名后跟一对尖括号,尖括号中指定需要特化的类型 4. 函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪的错误!
// 调用特化之后的版本,而不走模板生成了

有一个小坑:注意const指向,如下图

类模板特化
分为全特化和偏特化
全特化即是将模板参数列表中所有的参数都确定化;

注意:也可以是指针,引用,*等类型!
偏特化:任何针对模版参数进一步进行条件限制设计的特化版本。比如对于以下模板类
第一种常见用法:

第二种常见用法:

仿函数
仿函数(functor),就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了。
AS:less就是一个仿函数

个人认为这个仿函数有在之定义类型很有意义!尤其在一个类里实现大小排序转换!
template<>
struct LessDate*>
{ bool operator()(Date* x, Date* y) const { return *x *y; } };
继承
继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保 持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象 程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继 承是类设计层次的复用。

注意点:1,基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私 有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面 都不能去访问它。2,在实际运用中一般使用都是public继承,几乎很少使用protetced/private继承,也不提倡 使用protetced/private继承,因为protetced/private继承下来的成员都只能在派生类的类里 面使用,实际中扩展维护性不强。

基类和派生类对象赋值转换
派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用。这里有个形象的说法叫切片 或者切割。寓意把派生类中父类那部分切来赋值过去。 基类对象不能赋值给派生类对象!
在c语言中也有相似的,叫截断!
继承中的作用域
1. 在继承体系中基类和派生类都有独立的作用域。 2. 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏, 也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问) 3. 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏。 4. 注意在实际中在继承体系里面最好不要定义同名的成员
继承中的默认构造函数
我们下节在见吧!下节我将与题目一起结合起来与大家分享!

1493

被折叠的 条评论
为什么被折叠?



