美文网首页
极客班C++面向对象高级编程(下)第一周笔记

极客班C++面向对象高级编程(下)第一周笔记

作者: Wancho | 来源:发表于2016-08-08 12:01 被阅读0次

conversion function,转换函数

语法:如黄色部分所示,名称“operator+类型”,没有参数,它的返回类型要与名称中的类型一致,并且作者不能写出来。

non-explicit-one-argument ctor

这种构造函数,它是有两形参,且后一个形参有初值,所以它允许被一个实参调用,后面的形参就设为默认值。

所以调用示例中,编译器就会自动转换,以完成编译。

当conversion function和non-explicit-one-argument ctor并存时,调用示例中,就会有两种可以行的完成方法,编译器是没法决定选择使用哪一种的,所以这样会报错。

explicit-one-argument ctor

加了explicit关键字会让编译器不能将4转为Fraction,所以这里调用时编译器也会报错。

class模仿指针

pointer-like classes,关于智能指针

智能指针强化了普通指针所没有的功能,这里暂不详述。

上面的是C++1.0标准库简化后的智能指针;在指针能用到的操作符就是‘*’和‘->’,所以需要重载这两个操作符,而且是必须的。

语法: ‘*’的重载是直接返回指向的内容;而‘->’则是返回实际的指针,但是这样‘->’不就是消耗了吗?然而‘->’它在C++的定义是可以重复使用的,就是说完成重载函数后,它继续起作用。

pointer-like classes,关于迭代器

迭代器也相当于智能指针,它将指向容器的内容;

有所不同的是会有更多的操作符重载‘++’和‘--’,这些操作符作用于指针则是用于移位(内存地址),而这里则是改变在链表中的位置;

迭代器的‘*’的重载,要返回容器内容的数据;

而‘->’的重载则是返回容器内容数据的地址(即是返回指针)。

class模仿函数

function-like classes,所谓仿函数

模仿函数,即是要重载‘()’;

示例中,类模板是pair(一对的),所以写了两个struct,实现pair中两个对象的调用。

调用:

调用语法

标准库中,仿函数所作用的奇特的base classes

在C++标准库里面,有很多用仿函数,都会继承类似‘binary_function’的classes,它不会占用内存(实际上可能会占用为1)。

关于namespace

由于,在实际的开发团队中,各部门之间所写的代码,难免会有重名的情况出现;

或者自己写的测试程序也会有重名的情况,利用命名空间namespace,去解决重名情况,这样一来就可以在不同的namespace中都使用自己习惯的名称,不用再苦恼为变量和函数如何命名的问题。

关于模板

class template,类模板

所谓class template,就是在设计class时,把那些你认为允许使用者任意指定的类型抽出来,用自定义的关系字代替(这里用‘T’);

在调用时,就像上面一样,把指定类型写在‘<>’里面放在类名的后面。

语法:用template,表示T为未指定类型(可以是类,也可以是普通的数据类型)

function template,函数模板

所谓函数模板,就是允许函数不指明是哪一种类型调用和返回;

在调用时,编译器会进行实参推导,用来确定调用的类型;

要注意的是对象的类的功能要完善,要用到的操作符一定要重载。

语法:用template,表示T为未知的类型;

(在模板定义的语法中关键字class和typename的作用是完全一样的)

member template,成员模板

所谓成员模板(也可以说是模板成员),就是说它是类的成员,而且它本身又是一个模板。

特化模板

最前面的是普通的类模板,可以接收所有的类型,称为泛化模板;

而后面的三个则是特化模板,它是泛化模板中的特例,只能接收指定的类型;(如果泛化模板和特化模板同时存在,编译器会先检测特化模板)

但这样做不是跟不用模板一样吗?不一样,这样做可以为每种类型写不一样的内容。

模板偏特化(局部特化)

个数上的部分特化,将部分确定的形参类型和不确定的模板参数类型的标识符依次排序。(左边的一定要是确定的形参类型,而不能有非模板和模板参数穿插在里面)

范围上的局部特化,例如指针是对应类型的部分;

上面便是实现方法,在调用时编译器会判断,是否实参为指针形,而选择下面的一个(上一个和下一个的标识符没有直接的关联,可以写成右边的)

template template parameter,模板模板参数

上面的class,就是所谓的模板模板参数的写法,黄色的部分,是它与之不同的之处;

黄色部分表示,Container自身为模板,并且用第一模板参数‘T’作为它里面的参数类型(黄色里面的‘T’,就是指第一个模板‘T’);

但这样是还不是调用的,还需要增加中间的两行才可以(具体原因,会在下一个相关的章节详述)

对于上面的例子,第二模板参数也使用第一模板参数‘T’,作为它里面的参数;

但它不是模板模板参数,因为它的第二模板参数是预置了默认值,不完全是模板,

在调用时,它可以不写,而使用默认值,也可以写(第二个调用便是),但这样就不用理会第一参数的类型,而可以写上需要的类型。

这一点就可以与模板模板参数的定义分开。

关于C++标准库

在C++的标准库里面,已经涵盖了很多种容器(数据结构)和算法,标准库是很棒的团队写的,所以我们要善用标准库,而不是全都自己去写。

学习标准库的最好方法,就是自己写一个小程序,应用到标准库的每一个函数,而不是只去看网上相关的例子(光看,不实践)

C++11新标准

variadic template (数量不定的模板参数)

上面第2函数的第二模板参数便是,用typename...(记得是在typename后面加三个点),声明使用variadic template,表示接收一个参数包(里面有个数不定的参数)

接下来,在第2函数的第二个形参,相应的也需要的在后面,加上三个点,表示不定个数的参数包。

在调用时,也需要在参数包名称的后面加上三个点。

例子中的第2函数,会被辗转调用,直到把42输出是,参数包args...内没有参数了,print(args...)调用的就会是第1函数,从而结束运行。

例子是函数,当然,类也可以使用这个C++2.0的新特性。

auto

它的作用是,在变量声明时赋值的情况下,能让编译器通过判断值的类型,来确定变量的类型。

若在变量只声明不赋值时,编译器则无法确定变量的类型,所以最后的用法是不允许的。

ranged-base for

注释:decl表示变量,coll表示容器

例子中,for的里面的‘{}’表示容器(它也是C++11的新标准)

例子的for语句将会实现的是,把容器coll里的内容,逐个赋值给变量decl,直到容器遍历完成。

若想要改变容器内的值,则需要使用pass by reference。

关于reference

reference在定义时一定要有初值,而且不能被改变,直到它的生命结束。

例子中,r是代表x的,r拥有x的所以特性,也就是说r和它所代表的x的大小相同,地址相同(不过这是编译器所制造的假象)

二者不能并存的原因,是函数签名signature相同,使程序产生歧义Ambiguity,导致编译模棱两可;

函数灰色部分可以加const,const也是函数签名的一部分,所以二者其中一个加上const,就可以使它们两者并存。

相关文章

网友评论

      本文标题:极客班C++面向对象高级编程(下)第一周笔记

      本文链接:https://www.haomeiwen.com/subject/oocrsttx.html