C++相关概念和易错语法(10)(定位new、模板)

1.定位new

我们使用类来实例化对象,开辟空间的时候会自动去调用它的构造函数。但在那篇博客我就特意强调过,使用a.A()的方式是错误的,A()根本不会被识别为一个构造函数,而会被识别为A类型。因此我们要注意最好在实例化对象,开辟空间时就对它进行初始化。

当我们向内存池申请空间,使用malloc时无法直接调用构造函数,我们需要主动去调用构造函数,那应该怎么办呢?这就需要使用定位new了。

注意格式中new后面的括号内的是指针,之后跟初始化信息,单参数用小括号,多参数要用花括号。这种初始化也遵循隐式类型转换规则,和前面相似。

定位new的使用场景很少,如果我们想将一个已使用对象初始化,我们就可以使用这种办法,同时,它在内存池(池化技术)中使用比较多,池化技术即一次向堆申请一大块空间(减少操作系统负担),每次需要开辟空间时就会去找自己的内存池,用完将整块空间还回操作系统。

2.函数模板

C语言中,当我们需要使用实现方式相同,但数据类型不同的函数时,我们只有多依靠复制粘贴实现多个极为相似的函数,这样会使代码变得冗长,而且使得效率低下,因此C++中引入了模板的概念,具体又分为函数模板和类模板。

(1)函数前声明template<typename T1, typename T2...>(也可写作template<class T1, class T2...>),标志着这个函数针对广泛类型编程,也叫泛型编程

注意:template<typename T1, typename T2...>是函数模板的一部分,我们在使用的时候必须加上它且不能和函数主体分离

(2)函数模板看起来像是一个函数,但其实当我们用多种类型去调用这个函数模板时,底层编译器将这个模板实例化成了多个函数,分别去匹配。

虽然调试的时候看起来是一份函数,但在反汇编看得出来其实是多个函数构成函数重载

因此我们可以总结出模板的原理:编译器根据传参的类型实例化模板生成函数或类,本质上是多个函数或类,在C语言中我们需要自己写,现在是编译器帮我们实现了(半自动化),可以提高代码效率

(3)typename与class等价,两者一般可以互换

(4)template推演问题

当函数参数类型不一致时,函数模板推演就会产生歧义,这个时候我们需要显式实例化(可能会出现隐式类型转化),或者使用多个typename来处理歧义。对于返回类型,如果会产生多种返回情况,可通过auto类型来规避。

(4)函数匹配原则

普通函数、函数模板如果都能匹配我们的调用时,应该怎样规定优先级呢?

a.如果参数能直接匹配普通函数(有现成的函数),那就直接调用该函数而不会去调用函数模板。

如果匹配不上,会去匹配函数模板

b.要注意匹配普通函数时是看参数合不合适,编译器不会去看返回值合不合适。

c.要注意匹配普通函数是指完全匹配,并不会去考虑隐式类型转换如果需要通过隐式类型转换才能匹配普通函数的话,那就不符合规则(无const -> 有const也算作一种隐式类型转换),不会优先去匹配普通函数。

d.如果普通函数的参数不能匹配,就会去匹配更符合的函数模板,首先会去看参数部分,参数部分匹配会在完美匹配的基础上尽可能简洁,会用尽可能少的typename匹配

通过这里也可以看出,只要参数匹配更简洁,是不会去管返回值类型的。

关于完美匹配,一定要注意const,包括普通函数,无const -> 有const也算作一种隐式类型转换,这都不算作完美匹配

在这里我们就可以看出const T不能完美匹配无const类型,所以这个时候会去找有const修饰的typename,就算两个有const修饰的变量类型一致

 总结:先匹配普通函数,如果不能完美匹配,找函数模板,函数模板中尽可能完美匹配且简洁,实在不行就使用能隐式类型转换的。

3.类模板

(1)类模板和函数模板相似,但唯一需要注意的是类模板只能显式实例化类型

在这里,A a(2)的2是不能推演出类模板的类型的。类模板只能显式实例化类型,这是规定。

(2)类中的函数声明定义分离的时候,要注意类域的名称为:类的名称<实例化typename>,在写函数时也要在最前面生命template



不要声明定义分离到两个文件,会出现链接错误,在同一个文件可以分离

类模板的其他特性和函数模板一致,这里就不再赘述了。

  • 16
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值