初识C++之模板进阶与继承

本文详细探讨了C++中的模板进阶,包括函数模板、类模板、特化类型,以及非类型模板参数的使用。同时,文章深入讲解了继承的概念,如继承方式、访问限定符、继承与成员函数的关系、构造函数、拷贝构造函数、析构函数的使用。此外,还讨论了模板的优缺点和继承的特性,如隐藏、默认成员函数以及多继承中的菱形继承和虚继承问题。
摘要由CSDN通过智能技术生成

一、模板进阶

  1. 非类型模板参数

在模板中,模板参数分为类型形参非类型形参

类型形参就是我们经常用的,出现在模板的参数列表中,跟在class或typename之后的参数类型名称

非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用

我们来看下面的代码:

在上图中,我们写了一个Array类,里面的成员变量是一个数组。可以看到,它的数组大小是用N来控制的,是一个静态数组。当我们需要改变这个数组的大小的时候,就必须要去改变宏中定义的值。但是,如果我们现在需要两个Array类构建的数组,一个容量是10,另一个容量是100,此时宏就无法满足我们的需求。为了解决这种情况,就有了“非类型模板参数”。

在上图中,"T"是类型形参“N”就是非类型形参。可以看到,通过传非类型形参的方式,就可以控制开辟的数组容量。当然,我们也可以给N加上缺省值

虽然非类型形参是用常量当参数,但还是有要求的。就是非类型形参只能传入整型。浮点型、类对象、字符串都是允许作为参数的。

同时,非类型的模板参数必须要在编译期流能确认结果。传入的值不能是一个变量

在我们的库中,也存在一个array类,就使用了非类型参数。上面我们都是在类模板中使用。如果我们在函数模板中使用,就需要将函数模板显式实例化

如果我们用隐式实例化,就会出现报错。所以如果在函数模板中使用了非类型参数,就必须要显式实例化:

  1. 模板特化

在通常情况下,使用模板可以实现一些与类型无关的代码。但对于一些特殊类型的可能会得到一些错误的结果,需要进行特殊处理。

2.1函数模板

例如在以下的代码中:

我们提前准备了一个日期类。在这个日期类中提供了“<”重载以进行比较。但是我们运行上面的程序可以看到,虽然第一个和第二个比较都是正确的,但是第三个的比较结果确实错误的。原因很简单,我们这里传入的是p1和p2,比较的是指针大小。我们可以通过解引用的方式解决。但是,如果在这里,我们不想解引用,就想传指针进行比较呢?这个时候就需要针对某些类型进行特殊处理。以上图为例,我们要特殊处理的类型就是“Date* ”。此时,就可以用“模板特化”。

2.1.1函数模板特化使用

模板特化的使用方法也很简单:1.要有一个基础的函数模板;2.关键字template后面接一对空的<>;3.函数名后跟一对<>,尖括号中为需要特化的类型;4.函数形参表必须要和模板函数的基础参数类型完全相同,否则可能出现报错

模板特化的模板中,不存在参数。当我们遇到Date*时,我们不希望用left < right比较,而是用*left < *right比较

当我们再次运行该程序时,其他类型传入时就会去匹配Less(T left, T right)。但是当我们传入Date*时,编译器就会在匹配类模板之前,去下面看有没有针对该类型的模板特化,如果有,就去匹配模板特化:

2.2类模板

如果我们有以下代码:

我们现在想根据传入的某些类型,如double类型,进行特殊化处理,也可以使用模板特化:

类模板的特化和函数模板差不多。都要在template后的接一个空的<>。不同的是,类模板特化的特化类型要用<>写在类名后,与原模板的参数一一对应;并且类模板特化中不需要写成员变量。

2.3特化类型

特化一共有两种类型,全特化半特化(偏特化)

2.3.1全特化

全特化,即模板参数全部都进行特化。如下图:

该图中的Data类的两个参数都进行了特化,这就是全特化。

2.3.2半特化(偏特化)

半特化,也叫做偏特化。意思是可以仅对部分参数进行特化:

上图中就是一个半特化。我们只特化了第二个参数。在这种情况下,函数进入类模板调用函数之前,会下去下面找有没有针对对应参数的模板特化,有则调用对应的模板特化。因此,这里d2调用的就是模板特化而非原模板。

半特化时,我们必须要在template后面的<>中,填入未被特化的参数

如果全特化和半特化同时存在,它的匹配原则是:全特化 > 半特化 > 原模板

半特化还有一种使用方式,用于参数类型的进一步限制

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值