您的位置:首页 > 编程语言 > C语言/C++

Boolan C++面向对象高级编程(下)第四周笔记

2017-05-11 21:59 211 查看
Boolan极客班C++开发工程师笔记。

1.conversion function(转换函数)

对于系统的预定义基本类型数据,C++提供了隐式类型转换和显式类型转换两种类型转换方式:

int a=1,sum=0;
double b=1.111;
sum=a+b;          //隐式转换
sum=(int)(a+b); //显式转换
sum=int(a+b);   //显式转换


对于用户自定义的类类型与其他数据类型实现转换,C++提供了两种方法:

1.1 通过类型转换函数进行类型转换;

使用方法与操作符重载相似,定义见如下例子

operator double() const {
return (double) (m_numerator/m_denominator);
}
调用方法:

Fraction f(3,5);
double d=4+f;//调用operator double() 将f转为0.6


补充:

①类型转换函数只能作为类的成员函数,不能作为友元函数或者普通函数,因为被转换的是本类对象;

②在函数名前面不能指定函数类型,函数没有参数;

③函数中必须有return语句,即函数返回值的类型是函数声明中指定的类型;

④一个类可以定义多个类型转换函数,C++编译器会根据函数名自动调用相应的类型转换函数。

1.2 通过转换构造函数进行类型转换(non-explicit-one-argument ctor);

转换构造函数是将一个其他类型的数据转换成为类的对象,例子:

Fraction(int num, int den = 1)
: m_numerator(num), m_denominator(den) { }


除此之外,我们还需要重载运算符

Fraction operator + (const Fraction& f) {
return .....;
}


调用方法:

Fraction f(3,5);
Fraction d2=f+4;//调用non-explicit ctor 将4转为Fraction(4,1),然后调用operator+


1.3 explicit关键字

1.1和1.2两种方法共用时会出现歧义,解决方法:

在转换构造函数之前加上explicit,表示不允许将其他类型的数据转换成类对象。

2.pointer-like classes,关于智能指针

把class做的像pointer,但又希望它比pointer多些东西,这就是智能指针。首先,class里面一定有个真正的指针;其次,它得能代表一般的指针,因此就必须有指针的基本使用*和->,这需要操作符重载来实现。



3.pointer-like classes,关于迭代器

迭代器的作用是指向容器中的元素,也包含了指针的功能,具体代码见下面两张图。





4.function-like classes ,所谓仿函数

设计一个class让它的行为像一个函数。函数是怎么样的呢?有个(),所做出的对象可以接受()。 
标准库里有很多的仿函数,其实都是些class,所谓的仿函数就是类通过重载()来实现类似函数的功能,返回一个值。

具体的例子见下图



5.标准库中的仿函数的奇特模样







6.namespace

namespace的作用主要是防止函数或者类的名称冲突。

比如我们要测试20个函数,我们可以把每个函数单独放入到一个namespace中去,这样做每个函数都是完全独立的,不用考虑名称上的冲突。

7.模板

class template 和 function template前面的笔记中已经提到过。

7.1member tempate

先看下图的例子



class就是个模板,而成员里还有个模板,即黄色部分,称为成员模板。T1、T2可以变化,U1、U2也可以变化。 

为什么我们需要成员模板呢?见下图





鲫鱼和麻雀分别属于鱼类和鸟类的子类,用他们的类对象作为相应父类的初始化值肯定是可以的,但是一旦如上图所示pair类接收鱼类和鸟类类型后,该类的构造函数只能接受鱼类和鸟类作为初始化参数。这个时候我们就需要成员模板来解决pair类接受鲫鱼和麻雀类作为它构造函数的初始化类型。

7.2 specialization,模板特化

泛化就是模板,特化的意思就是指你作为一个设计者,你可能要面对一些特殊的类型要单独处理。 
解释:上面的是泛化,下面的是特化。且下面的都对()进行重载。 



7.3partial specialization,模板偏特化

泛化又分为:全泛化(full specialization)和(partial specialization,模板偏特化(局部特化)) 
偏特化:个数上的偏,范围上的偏。 
如下图,个数上的偏特化。一定要从左边到右边,不能跳着来 



范围上的偏特化,如下,T是任意类型,现在把它范围缩小成指针,如下 



7.4template template parameter,模板模板参数

模板的参数本省也可以是模板,具体代码如下:

temeplate<tpyename T,
template <typename T>
class Container
>
Class XCls {
private: Container<T> c;
......
};

template<typename T>
using Lst=list<T,allocator<T>>;
如果作为模板参数的模板只需要一个参数,我们可以写成如下格式:

XCls<string,Lst> mylst2;
如果需要的参数不止一个,且没有默认值,就不能这么写:

XCls<string,list> mylst1;


8.关于C++标准库

标准库包含了容器(Container),算法(ALgorithms),迭代器(Iterators),仿函数(Functors)等。

最好的学习方法是把里面的方法全部自己用一遍!

9.C++11后的一些新语法

9.1variadic template

C++11之前模板必须指定参数个数,现在C++11给出新的语法,模板参数个数可以变动,具体代码如下:
void print()
{
}

template<typename T, typename... Types>
void print(const &T, const Types&...args) {
cout << firstArg << endl;
print(args...);
}


...就是一个所谓的pack(包)
用于template parameters,就是template parameters pack(模板参数包)

用于function parameter types,就是function parameter types pack(函数参数类型包)

用于function parameters,就是function parameters pack(函数参数包)

9.2 auto

auto是C++中的一个语法糖,可以让编译器自动推算变量类型。

不要极端地认为全部都使用auto,首先作为初学者在没有完全清楚变量的类型的情况下不建议,其次并不是所有情况下都能使用auto,比如下面这种情况就不能使用auto:



9.3range-base for

这是for循环的一种新的写法,也是C++11的一种语法糖,依赖于迭代器,格式如下:

for (declaration : expression){
statments;
}
expression必须是一个序列,比如vector,数组,string等。

注意点:pass by value和pass by reference的不同作用,前者不改变expression里面的对象,后者可以

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: