C++编程思想第二卷(实用编程技术)摘要-阿里云开发者社区

开发者社区> leonwei> 正文

C++编程思想第二卷(实用编程技术)摘要

简介:
+关注继续查看

在c++编程思想的第二卷中介绍了很多更深入的c++特性,这是现代C++编程的精髓

模板

1.一般类的声明和定义都在H和CPP两种文件中,主要是怕连接时的多重定义,但是对于模板可以放心的将他们都放在H文件中,因为template后面的东西编译器不会为其分配空间,知道有一个模板实例告知。如果不适用内敛的方式,在每次定义模板的函数前都要声明template,而且声明中的类名后面要加<参数>

2.可以这样定义模板类

template<class T,classu…>

template<class T,int size…>

template<class T,int size=100…>//一个默认值

定义函数模板

template<class T,classu…> void f();

template<typename T…> void f();

在使用函数模板时通产个可以省略模板参数(在可以推断出来的时候)

可以这样定义成员函数模板:在类的内部,定义一个函数template<class T,classu…> void f();这个甚至可以是构造函数。

3关键字typename:表示他限定的那个词是一个类型(类内的)而不是一个成员:typename Seq<T>::iterator it;如果不加这个关键字,那么编译器会认为iterator是成员,有语法错误,加上后表示这是一个类型,而it是一个变量。同样template关键字也只能用在模板类中,这个关键字表示他后面出现的那个<为模板参数列表符而不是小于号。

4.模板的特化

全特化:

template <class Window, class Controller>
class Widget
{
... generic implementation ...
};

template <>
class Widget<ModalDialog, MyController>
{
... specialized implementation ...
};
其中 ModalDialog 和 MyController 时定义好的classes,在这里当你构建Widget<ModalDialog, MyController>实例时,将用下面的构造函数,而其他的用上面的,上面的称泛化,下面的叫特化

偏特化:就是部分参数特化,部分泛化

template <class Window> // Window
class Widget<Window, MyController> // MyController
{
... partially specialized implementation ...
};

这里window是范化的,MyController是特化的,也就是构造一个任意类和MyController的实例时调用这个构造函数

这个构造可以很复杂,泛化的类可以也是一个模板类

template <class ButtonArg>
class Widget<Button<ButtonArg>, MyController>
{
... further specialized implementation ...
};

5.局部类:

也就是定义在函数中的类,这个类不能定义static成员变量,也不能存取non-static的局部变量

void Fun()
{
class Local
{
... member variables ...
... member function definitions ...
};
... code using Local ...
}

函数不能偏特化

 

异常处理

1.捕获所有异常使用catch(...)

2重新像更高一级跑出异常要在catch子句中写一个throw

3、不捕获异常,如果异常没有被任意一个层次捕捉到,那么就睡直接调用程序中的terminate函数,它的默认实现是abort(),这不是一个正常终止程序的方式,全局变量不被析构

可以使用set_terminate来设置自己的terminate函数。

4、标准异常类:exception,他有很多派生类提供各种异常,可以查阅

5异常规格说明:void f();可能跑出各种异常void f() throw(a,b..);理论上只抛出这些异常;void f()throw();理论上不抛出任何异常;

如果程序抛出了不在描述中的异常,那么会调用unexpected()函数,默认下这个函数执行terminate函数,可以使用set_unexpected()来重新设置这个函数。

函数对象:

他是实现了重载()的类的一个实例。

在stl的算法中,这个类的实例通常被用来作为判定函数,它并不是函数,但是因为他重载了(),可以调用a(),类似于一个函数,所以叫做函数对象,它比简单的判定函数的好处在于它是一个类的对象,它里面可以存储更多的信息

在通用算法中,算法有几元,它的判定函数就必须使用几元,算法的元是指它传递到判定函数中的参数的个数。

STL算法:

1、填充和生成:fill() fill_n() generate()

2、计数:count() count_if()

3、操作序列: copy() copy_backward() reserve()[倒置] reserve_copy()[倒置后复制它出] rotate()【交换位置】rotate_copyright()

                      next/preve_permutation()[数学上的排列组合] rondom_shuffle()【随机重排】 partition()[划分,将满足某个条件的元素移到开头]

4、查找和替换: find/findif()[线性查找] adjacent_find()[查找两个临近的相等元素] find_first_of()[在第二个序列上查找与第一个序列上某个元素相等的元素]

                        search()[查找第二个序列是否出现在第一个序列中(次序也一致)] find_end()[同serch,但是返回最后出现的那一段位置]

                        search_n()[查找一组相邻的同样的值] min/max_element()[找到最小/大的那个值首次出现的位置] replace()replace_if()replace_copy_if()[找到后替换]

5、比较范围:equal()【两个范围是否元素相同顺序相同】lexicographical_compare()[比较两个范围的字典编纂顺序]

6、删除元素:remove() remove_if() remove_copy_if()

                    unique()[删除相邻的同样的元素(相邻的值留下一个),通常之前先用sort(),这样可以每个元素都只有一个]

7、排序合并:sort()[按升序排序] stable_sort()[按升序排序并保持相等元素的顺序] partitial_sort()【部分排序】nth_element()[保证其中一个元素作为划分点,左侧小于它,右侧大于他,用

               于算中值和百分点] binary_serach()[在已排序的范围内寻找] upper_bound()[在一个范围内找出大于一个值的元素最后出现的那个位置]

               equal_range()【找到在一个范围内某只出现的范围】merge() inplace_merge()[合并]

                在已拍好序的集合上的集合运算

                     include()【是否包含】set_union/differrence/intersection/symmetric_difference()

8、堆运算:通常可以将一个序列转化成一种类似于对的结构,在这里面便于一次找出优先权最高的元素

                make_heap()[将序列转化成堆]push_heap() pop_heap()[将堆顶的元素一道序列的最尾断,不是移除]sort_heap()【将一个堆序的序列重新变成一个按顺序排列的序列】

9、对一个范围的成员全部应用某种运算;foreach()【对每个成员使用某个函数】transforma()【对每个成员使用某个函数并把结果写入一个序列】

10、数值算法:accumulate()【对所有元素循环的调用一个函数得到一个累计的值】inner_product()【内积】partitial_sum()adjacent_diffrence()[得到原数列相邻元素的差]

11、其他:pair():一个封装两个对象的类,通过make_pair()构造

                distance():返回两个迭代器之间的距离,增加次数

                back_inserter/inserter/front_inseeter():为一个容器构建一个迭代器,这个迭代器只用于在某个位置进行插入

                min() max() [比较]  swap()[值交换]

容器:
容期间可以通过assign进行互相的转换
vector:它可以快速的访问,但支不持在中间插入,它溢出时的代价很高,因为先要分配更大的存储空间,然后把原先的内容拷贝过来。可以使用reserved告知预先要多大的空间,而使一个整数作为它的构造函数的第一个参数的做法则是把所有的成员默认初始化。
使用vector的最有效的方法是,在开始使用reserved告诉预先需要的空间大小,然后只在序列后端插入或删除元素
deque:在不确定对象数量时尽量用它而不用vector,因为它在两端插入或删除的效率更高。但是随机访问不如vector。它不支持中间插入。
list:在任意地方插入删除,但是不支持随机访问,只能遍历,遍历效率也较慢。如果是较大较多的对象,尤其是构造很麻烦的对象,尽量使用它,如果要进行排序等更是的,因为在list中这通常只需要改变指针的指向而已。

适配器:stack、queue、prioruty_queue为适配器,他们是用vector、list和dequeue来实现的,每一个适配器都可以用它们分别实现。它们的默认方式通常被认为是最好的。
prioruty_queue:出于安全,它没有设计迭代器,但是可以使用mack_heap等操作讲vector模拟成优先队列。
关联式容器:set/multyset/map/multymap都是,它们的特点是将一个值关联一个关键字,set可看成只有关键字。
set:存放唯一的且排过序的成员。


表示二进制位:
c中没有表示二进制数值的方法,只有十进制和十六进制,有两个方法可以代替。
bitset类:它表示有固定位数的二进制串。

vector<bool>容器

valarray容器,他可以操纵一组数组,然后进行各种数值运算,可以对其中的一部分切片出来分析。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
4070 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
4494 0
C++编程思想1
学了好久的 C++了 发现自己对于C/C++还是没有深入的了解 于是 咬咬牙啃起了 C++编程思想 希望能有所感悟 。。 我以前是直接学C++的对于C不是很了解,然而又是在VC下 学习 所以 没有好好的 去学习 标准C++,直到我 看起C++编程思想  我发现真应该从头再学一遍了  。
641 0
c++编程思想2 --友元存储控制
 友元friend在c++中的应用  我们知道在c++的类访问权限中,private和 protected在类外面进行访问的时候 会因为权限而不能访问 ,友元就解决了这个问题 。 可以这样理解,他为外部的 函数 或者类 进行了 访问授权,其实这已经超出OOP的范畴,但是对于C++而言是以实用为主,所以说C++并不是完全面向对象的语言 C++这一特性就破坏的C++的安全性 。
685 0
+关注
87
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载