一、循环、递归与概率
1、递归基础知识
一个过程或函数直接调用自己本身或通过其他的过程或函数语句间接地调用自己的过程或函数,称为递归过程或函数。
二、STL模板和容器
1、向量容器
(1)介绍一下STL和包容器,如何实现?举例实现vector。
c++的一个新特性就是采用了标准模板库(STL)。所有主要编译器销售商现在都把标准模板库作为编译器的一部分进行提供。标准模板库是一个基于模板的容器类库,包括链表,列表、队列和堆栈。标准模板库还包括许多常用的算法,包括排序和查找。
标准模板库的母的是提供对常用需求重新开发的一种替代方法。标准模板库已经经过测试和调试,具有很高的性能并且是免费的。最重要的是,标准模板库是可重用的。当你知道如何使用一个标准模板库的容器后,就可以在所有的程序中使用它而不需要重新开发了。
容器是包含其他对象的对象。标准c++库提供了一系列的容器类,他们都是强有力的工具,可以帮助c++开发人员处理一些常见的编程任务。标准模板库容器类有两种类型,分别是顺序和关联。顺序容器可以提供对其成员的顺序访问和随机访问。关联容器则经过优化关键值访问它们的元素。标准模板库在不同操作系统间是可移植的,所有标准模板库容器类都在namespace std中定义。
三、面向对象
面向对象设计的三原则:封装、继承、多态。
(1)类和结构
问:structure是否可以拥有constructor/destructor及成员函数?如果可以,那么structure和class还有区别么/
答案:区别是class中变量默认是private,struct中的变量默认是public。struct可以有构造函数、析构函数,之间也可以继承,等等。c++中的struct其实和class意义一样,唯一不同的就是struct里面默认的访问控制是public,class中默认的访问控制是private。c++中在struct关键字的唯一意义就是为了让c程序员有个归属感,是为了让c++编译器兼容以前用c开发的项目。
问:哪一种成员变量可以在同一个类的实例之间共享?
答案:必须使用静态成员变量在一个类的所有实例间共享数据。如果想限制对静态成员变量的访问,则必须把它们声明为保护型或私有型。不允许用静态成员变量去存放某一个对象的数据。静态成员函数是在这个类的所有对象间共享的。
常量必须在构造函数的初始化列表里面初始化或者将其设置成static。
(2)构造函数和析构函数
a.析构函数可以为virtual型,构造函数则不能。那么为什么构造函数不能为虚呢?
虚函数采用一种虚调用的方法。虚调用是一种可以在只有部分信息的情况下工作的机制,特别允许我们调用一个只知道接口而不知道其准确对象类型的函数。但是如果要创建一个对象,你势必要知道对象的准确类型,因此构造函数不能为虚。
b.如果虚函数是非常有效的,我们是否可以把每个函数都声明为虚函数?
不行,这是因为虚函数是有代价的,由于每个虚函数的对象都必须维护一个v表,因此在使用虚函数的饿时候都会产生一个系统开销。如果仅是一个很小的类,且不想派生其他类,那么根本没必要使用虚函数。
(3)c++三大特征
封装、继承、多态。
封装可以隐藏实现细节,使得代码模块化,继承可以扩展已存在的模块,它们目的都是为了:代码重用。而多态是为了实现另一个目的:接口重用。
什么是多态?
eg:开门,开窗户,开电脑,这里“开”就是多态。
多态性可以简单概括为“一个接口,多种实现”,是通过虚函数实现的。基类提供一个虚接口,其派生类重写这个接口,这样就构成了多态。
面向对象———封装(特性之一)
封装是面向对象的特征之一,是对象和类概念的主要特性。封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。一旦定义了一个对象的特性,则有必要决定这些特性的可见性,即哪些特性对外部世界是可见的,哪些特性用于表示内部状态。在这个阶段定义对象的接口。通常,应禁止直接访问一个对象的实际表示,而应通过操作接口访问对象,这称为信息隐藏。事实上,信息隐藏是用户对封装性的认识,封装则为信息隐藏提供支持。封装保证了模块具有较好的独立性,使得程序维护修改较为容易。对应用程序的修改仅限于类的内部,因而可以将应用程序修改带来的影响减少到最低限度。
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
封装好处:
1.将变化隔离;
2.便于使用。
3.提高重用性。
4.提高安全性。
封装原则:
将不需要对外提供的内容都隐藏起来。
把属性都隐藏,提供公共方法对其访问。
private:关键字
A:用于修饰成员变量和成员方法。
B:被修饰的内容在其他类中是不可以被访问的。
注意:私有仅仅是封装的一种体现而已。
面向对象———继承(特性之二)
继承是一指一个对象从另一个对象获得功能的过程,它提供了一种明确表述共性的方法。是一个不断向上抽取的过程
例如:所有的Windows应用程序都有一个窗口,它们可以看作都是从一个窗口类派生出来的。但是有的应用程序用于文字处理,有的应用程序用于绘图,这是由于派生出了不同的子类,各个子类添加了不同的特性。
继承与封装可以共同作用.如果一个给定的类封装了某些属性,它的任何子类将会继承同样得属性,另加各个子类所有得特有属性。
继承优点:
1,提高了代码的复用性。
2,让类与类之间产生了关系。有了这个关系,才有了多态的特性。
面向对象———多态(特性之三)
多态简单说,就是某一类事物多种存在形态。例如,猫对应的类型是猫类型,但同时他也是动物中的一种,也可以把猫称为动物。又比如,同样的选择编辑-粘贴操作,在字处理程序和绘图程序中有不同的效果。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数扩展性。
1,多态的体现
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象。
2,多态的前提
必须是类与类之间有关系。要么继承,要么实现。
通常还有一个前提:存在覆盖。
3,多态的好处
多态的出现大大的提高程序的扩展性。
4,多态的弊端
提高了扩展性,但是只能使用父类的引用访问父类中的成员。
(4)重载和覆盖有什么不同?
虚函数总是在派生类中被改写,这种改写被称为“override”(覆盖)。
override是指派生类重写基类的虚函数,就像我们前面在B类中重写了A类中的foo()函数。重写的函数必须有一致的参数表和返回值(c++标准允许返回值不同的情况,但是很少有编译器支持这个特性)。override这个单词好像一直没有合适的中文词汇来对应。有人翻译为“f覆盖”,还贴切一些。
overlode约定俗称地被翻译为“重载”,是指编写一个与已有函数同名但是参数表不同的函数。例如一个函数既可以接收整型数作为参数,也可以接收浮点数作为参数。重载不是一种面向对象的变成,而只是一种语法规则,重载与多态没有什么直接关系。