本文已参与「新人创作礼」活动,一起开启掘金创作之路。
conversion function转换函数
转换不可能改变数据,所以通常都要加const
编译器有可能找一找有没有全局的+这个函数,看能否让这行通过编译,现在没有,所以看看能否把f转为double,找到了黄色那块,所以可以。
non-explicit-one-argument ctor
one argument是指一个实参,这里是两个parameters,另一个是默认值
首先看有没有设计+这个函数,但是它要求右边是一个fraction,这里确是4,所以要看看能不能把4转为fraction,所以发现上面一块函数。
这个函数可以把别的东西转换为这种东西,与上一个函数方向相反,但是口语上的转换函数是指上一种conversion function
conversion function vs. non-explicit-one-argument ctor
如果两者并存,编译器就不知道怎么办了(当有多条路时编译器就报错,产生了歧义)
explicit-one-argument ctor
explicit是告诉编译器不要自动的给我做这种事,这里就是只有当我以构造函数的形式需要的时候才调用他
所以这里+就是失败了,不能把4转为fraction
这个关键字用的比较少,只有构造函数前,当然这只是为了强调,其实模板的很小的地方也用得到
下面是标准库的一个例子,更有说服力
<bool这里是模板的偏特化,还没谈,之后会谈,它是容器里元素都是bool值
注意重载函数的返回值,它返回值应该是真或假,但是没有,它是另外一个class,这种设计手法叫proxy代理,用reference去代表他本来应该传回来的东西,这个设计手法不谈,它是一个有名的设计模式。reference应该要代表一个bool值,所以他就应该有个转换函数转为bool
pointer-like classes,
关于智能指针
一个c++的class做出来可能像两种东西,一种所产生的对象像指针,下一个主题就是像一个函数
为什么要把一个class做出来像一个指针,因为想比指针再多做一些事情,所以通常这样做出来的东西又叫智能指针
c++在2.0前有一个智能指针:auto pointer,2.0之后有好几个智能指针,包括现在看到的shared pointer,他们长相都类似这样:他们里头一定有一个真正的指针
这里是模拟shared pointer的写法,早起也是这种写法,所以确实可以想象成标准库源代码,只不过到了2.0又变得很复杂了
这里不去讨论他智能在哪里,只讨论语法
这两个重载函数在这类智能指针基本是固定的
这里有一点注意的是:
sp得到的是px,这里没问题,但下一个sp->得到了px,后面的->消耗掉了,但是->作用下去得到的结果能够继续作用下去,所以就合力了。
关于迭代器
迭代器就是要代表容器里的一个元素,指向一个元素,因此也像一个指针,可以说是智能指针
现在只谈迭代器作为另一种智能指针我们要注意他的操作符重载
迭代器之外的智能指针可能不必去处理++,--等
这里的设计和之前的智能指针不一样。首先要注意data才是类的对象,迭代器要取的是里面的data,所以*要先得到结构体然后得到data。对于第二个,同样注意函数是data的函数。
function-like classes,所谓仿函数
如果要问为什么让对象像指针或者函数,因为不能一言以蔽之,所以先不谈了,其他更多课程里可能会有好的体会。
如何像一个函数?函数有个函数名称,用()作用上去,()叫function call operater,函数调用操作符,所以任何一个东西能接受()操作符,就把他叫做函数或者像函数的东西。
可以发现,这些仿函数都继承自一些东西,感觉并没有什么用,所以到底是继承了什么呢?
标准库中,仿函数所使用的奇特的base classes
至于为什么要继承,这是很大的一个题目,不适合在这谈,在标准库那节课谈为什么要继承他,这里只是让看一下,标准库里的仿函数都继承自base classes。
不过猜猜这两个类的大小是多少。是,0,因为里面没有变量也没有函数。但是如果用sizeof就是1,因为实现上由于一些限制可能是1。
namespace经验谈
由于不想测试一堆事变成一堆程序,太啰嗦,所以总是放在同一个程序里,也方便自己以后看,所以只有一个main,里头如果我要测20个动作或者20个事会有20个函数,20个函数每个都包在一个namespace里。