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容器,他可以操纵一组数组,然后进行各种数值运算,可以对其中的一部分切片出来分析。

目录
相关文章
|
2月前
|
敏捷开发 算法 安全
【 第十章】软件设计师 之 软件工程概述
软件设计师 之 软件工程概述 备考资料
【 第十章】软件设计师 之 软件工程概述
|
2月前
|
敏捷开发 IDE 测试技术
编码之禅:高效编程的艺术与实践
【7月更文挑战第58天】在软件开发的广阔天地中,高效编程是每位程序员追求的终极技艺。本文将探讨提升编程效率的关键要素,包括清晰的思维逻辑、熟练的工具运用、代码质量的持续追求以及有效的团队协作。通过实例分析和个人经验的分享,我们将一窥高效编程背后的秘密,并探索如何将这些原则融入日常的编码实践中。
|
4月前
|
C++
c++primer plus 6 读书笔记 第十一章 使用类
c++primer plus 6 读书笔记 第十一章 使用类
|
5月前
|
存储 缓存 算法
【C 言专栏】C 语言实现算法的高效性
【5月更文挑战第6天】本文探讨了C语言在实现高效算法上的优势,包括其高效性、灵活性、可移植性和底层访问能力。关键点包括选择合适的数据结构(如数组、链表、树和图)、应用优化策略(如减少计算、空间换时间、分治和动态规划),以及内存管理和代码优化技巧。通过实际案例(如排序和图遍历算法),阐述了如何利用C语言实现算法高效性,并强调在实践中不断探索和优化以提升算法效率。C语言在计算机科学中的重要地位使其成为实现高效算法的首选工具。
96 0
【C 言专栏】C 语言实现算法的高效性
|
5月前
|
敏捷开发 算法 Java
代码之禅:高效编程的艺术与实践
【5月更文挑战第28天】 在数字化时代的浪潮中,编程已成为一种现代魔法,它不仅塑造了科技的边界,也重新定义了问题解决的途径。本文将深入探讨如何通过持续的技术精进与哲学思考,提升编程效率并创作出优雅、高效的代码。我们将从编程语言的选择、算法优化、架构设计,到开发流程和团队协作的实践等方面,揭示那些隐藏在成功项目背后的通用原则。文章的核心旨在于启发读者形成自己的编程哲学,让代码不仅仅是功能的实现,更是艺术的表达。
|
5月前
|
存储 算法 程序员
【软件设计师】通俗易懂的去了解算法的特性和要求
【软件设计师】通俗易懂的去了解算法的特性和要求
|
5月前
|
设计模式 存储 算法
【软件设计师—基础精讲笔记7】第七章 面向对象技术
【软件设计师—基础精讲笔记7】第七章 面向对象技术
98 1
|
5月前
|
自然语言处理 Java 编译器
【软件设计师—基础精讲笔记10】第十章 程序设计语言基础
【软件设计师—基础精讲笔记10】第十章 程序设计语言基础
76 1
|
5月前
|
算法 程序员 开发工具
代码之禅:技术感悟与编程实践的融合
【4月更文挑战第27天】 在数字世界的纷繁背后,每一行代码都承载着逻辑与创造的力量。本文以个人编程实践出发,探讨技术发展与个人成长之间的微妙联系。文章不仅记录了作者在技术探索过程中的心得体会,还分享了如何将抽象的编程概念与具体的应用场景相结合,提升开发效率和项目质量。从初学者的困惑到熟练者的自信,再到高手的从容,每个阶段都有其独特的挑战与收获。通过反思与总结,旨在为同行提供一种思维上的启发和技术上的参考。
|
5月前
|
程序员 Python
类的设计奥秘:从代码到架构的科普全解
类的设计奥秘:从代码到架构的科普全解
86 2