1. 运算符<<(“送出”)作为输出运算符,>>(“取入”)作为输入运算符;
cout:标准输入,cin标准输出;一般与<< >>结合使用。
int book_count = 0;
cout << "The value of book_count: " << book_count;
输出:the value of book_count: 0
2. 可以将变量定义置于函数任意位置?(待确认)
3. 头文件及文件的后缀在C++ 的不同实现中不尽相同,这也是标准C++ 没有指定头文件后缀的一个原因。请查阅你的编译器的用户指南以确定在当前平台上使用什么后缀。
4. #include <iostream>
using namespace std;
5. 调用C++ 编译器的命令的名字在不同的实现中也不相同,可以通过参考手册或系统管理员获得系统的C++ 命令名。
6. 内置数据数据类型:整数类型int ,浮点数类型float ,字符类型char ,以及只有false 和true 两个值的布尔类型boolean 。
标准库类:字符串string ,复数complex number, 向量vector 和列表list。
复合数类:指针和数组类型,引用
// 为了使用string 对象下面的头文件是必需的,Getting Started chapter_title 是一个向量包含有20个字符串类型的元素
#include <string>
string current_chapter = "Getting Started";
// 为了使用vector 对象下面的头文件是必需的,要定义一个能够存放20个整数的向量对象
#include <vector>
vector<string> chapter_titles( 20);
数组:int fibon[ 9 ] = { 0, 1, 1, 2, 3, 5, 8, 13, 21 };
引用:引用reference 即IntArray &rhs 引用是一种没有指针语法的指针
7. 在命令行中定义预处理器常量,编译程序时可以使用-D选项并且在后面写上预处理器常量的名字。
编译C++ 程序时编译器自动定义了一个预处理器名字__cplusplus注意前面有两个下划线 因此我们可以根据它来判断该程序是否是C++ 程序以便有条件地包含一些代码。例如
#ifdef __cplusplus
// 不错我们要编译C++
// extern "C" 到第7 章再解释
extern "C"
#endif
int main( int, int );
在编译标准C 时编译器将自动定义名字__STDC__ 当然__cplusplus 与__STDC__ 不会同时被定义 。另外两个比较有用的预定义名字是__LINE__和__FILE__。__LINE__记录文件已经被编译的行数,__FILE__包含正在被编译的文件的名字。另外两个预定义名字分别包含当前被编译文件的编译时间__TIME__和日期 __DATE__。
if ( element_count == 0 )
cerr << "Error: " << __FILE__
<< " : line " << __LINE__
<< "element_count must be non-zero.\n";
8. assert() 是C 语台标准库中提供的一个通用预处理器宏。#include <assert.h>,这个头文件的C++ 名字是cassert。头文件为在#include <assert.h>时,程序文本文件中使用名字assert() 而无需使用using指示符。
assert() 将测试条件是否满足,为了后面的程序能够正确执行我们必须断言一个必需的前提条件,如果这个条件为假 断言失败,则程序将输出诊断消息,然后终止。
9. 标准输入输出cin,cout,cerr。
cout >> "word read is: " >> word >> '\n';是否存在错误?
连续出现的输出操作符可以连接在一起,cout << "The sum of v1 + v2 = " << v1 + v2 << endl;
连续出现的输入操作符也可以连接起来,cout >> "word read is: " >> word >> '\n';
10. 文件输入输出
#include <fstream>
为了打开一个输出文件我们必须声明一个ofstream 类型的对象。为了打开一个文件供输入我们必须声明一个ifstream 类型的对象。
ofstream outfile( "out_file" );
ifstream infile( "in_file" );
11. 在C++ 中指针的主要用处是管理和操纵动态分配的内存
静态与动态内存分配的两个主要区别是:
1. 静态对象是有名字的变量,我们直接对其进行操作。而动态对象是没有名字的变量,我们通过指针间接地对它进行操作。
2. 静态对象的分配与释放由编译器自动处理。动态对象的分配与释放必须由程序员显式地管理。它通过new 和delete 两个表达式来完成。
int *pint = new int( 1024 ); delete pint;
int *pia = new int[ 4 ]; delete [] pia;
12. 基于对象设计的类
class classname {
public:
// 公有操作集合
private:
// 私有实现代码
protected:
//保护
};
classname(类名)代表的是一个新的数据类型,我们可以用它来定义这种类型的对象就像用内置的类型定义对象一样。
成员访问操作符:用于类对象的点操作符“.” 以及用于类对象指针的箭头操作打“->”。
在类体中公有public 部分的成员在一般程序的任何地方都可以访问它们,出现在私有private 部分的成员只能在该类的成员函数或友元friend 中被访问。
公有成员提供了该类的公有接口public interface ——即实现了这个类的行为的操作集合,私有成员提供私有实现代码private implementation ——即存储信息的数据。
13. 内联函数
内联函数不会引入任何函数调用,在类定义中被定义的成员函数会被自动当作是内联函数。此外我们也可以用inline 关键字显式地要求一个函数被视为内联函数。
14. 构造函数
构造函数是一种特殊的类成员函数,专门用于初始化对象。如果构造函数被定义了,那么在类的每个对象第一次被使用之前,这构造函数就被自动应用在对象上。为一个类确定必要的构造函数是程序设计不可缺少的一部分。为了定义一个构造函数,我们只要给它与类相同的名字即可,另外我们不能给构造函数指定返回值,但是可以给类定义多个构造函数,尽管它们都具有相同的名字,但只要编译器能够根据参数表区分它们就行。
explicit IntArray( int sz = DefaultArraySize ); 被称为缺省构造函数default constructor 用为它不需要用户提供任何参数。IntArray array1( 1024 );IntArray array2;传默认值DefaultArraySize
IntArray( int *array, int array_size );
IntArray( const IntArray &rhs );用另外一个IntArray 对象来初始化当前的IntArray 对象
15. 函数重载机制
函数重载允许两个或更多个函数使用同一个名字限制条件是它们的参数表必须不同参数类型不同或参数的数目不同根据不同的参数表编译器就能够判断出对某个特定的调用应该选择哪一个版本的重载函数。
16. 在类体的外面定义类的成员函数惟一的语法区别是要指出成员函数属于哪个类,这可以通过类域操作符class scope operator 来实现.
双冒号:: 操作符被称为域操作符scope operator, 当与一个类名相连的时候它就成为一个类域操作符.
全局域的对象在它被定义的整个文件里一直到文件末尾都是可见的,在一个函数内被定义的对象是局域的local scope ,它只在定义其的函数体内可见,每个类维持一个域,在这
个域之外它的成员是不可见的,类域操作符告诉编译器后面的标识符可在该类的范围内被找到。
17. 析构成员函数
每个类对象在被程序最后一次使用之后它的析构函数就会被自动调用,我们通过在类的名字前面加一个波浪线~ 来标识析构函数。一般地析构函数会释放在类对象使用和构造过程中所获得的资源。
18. 面向对象的设计:继承,基类,派生类(子型类)
如果希望防止派生类直接访问某个成员,我们就把该成员声明为基类的private 成员,如果确信某个成员提供了派生类,需要直接访问的操作或数据存储,而且通过这个成员派生类的实现会更有效,则我们把该成员声明为protected。设置成 protected ,也就是实际上允许后续派生的类访问实现细节。
class IntArrayRC : public IntArray
冒号定义了IntArrayRC 是从IntArray 派生而来的。关键字public 表明派生类共享基类的公有接口。IntArrayRC 类型的对象可以用在任何可以使用基类类型对象的位置上。
C++ 支持另外两种形式的继承:多继承multiple inheritance 也译多重继承 ,也就是一个类可以从两个或多个基类派生而来.以及虚拟继承virtual inheritance ,在这种继承方式下基类的单个实例在多个派生类之间共享.
18. 泛型设计
关键字template 引入模板参数由一对尖括号< > 括起来,本例中有一个参数elemType 。关键字class 表明这个参数代表一个类型标识符。elemType 代表实际的参数名,它在Array类定义中出现了七次都是作为实际类型的占位符。
template < class elemType >
使用:Array<int> ia(array_size);这些实例声明就是在类模板名的后面加上一对尖括号,然后在里面写上数组的实际类型。
19. 异常处理
1. 程序中异常出现的点一旦识别出程序异常,就会导致抛出raise 或throw 异常。
2. 程序中异常被处理的点
程序异常的抛出与处理位于独立的函数或成员函数调用中,找到处理代码通常要涉及到展开程序调用栈Program call stack, 一旦异常被处理完毕就恢复正常的程序执行,但不是在发生异常的地方恢复执行过程,而是在处理异常的地方恢复执行过程。C++ 中异常的处理由catch子句来执行。
throw string( "internal error: adump27832" );
catch( string exceptionMsg ) {......}
20. try块
在try块中执行的代码所抛出的异常(调用的函数中抛出的异常或直接使用throw抛出的异常),通常会被其中一个catch子句处理。与其他块语句一样,try块引入局部作用域,在try块中声明的变量,包括catch子句中声明的变量,不能在try外面引用。
21. 使用其他名字来命名数组
名字空间别名namespace alias 允许用一个可替代的短的或更一般的名字与一个现有的名字空间关联起来。
namespace LIB = IBM_Canada_Laboratory;
22. 向量
vector<string> svec( 10 );
// size为8 的vector
// 每个元素都被初始化为0
vector<int> vec1( size );
// size为8 的vector
// 每个元素都被动始化为1024
vector<int> vec2( size, value );
// vtc3的size 为4
// 被初始化为ia的4 个值
int ia[4] = { 0, 1, 1, 2 };
vector<int> vec3( ia, ia+4 );
// vec4是vec2 的拷贝
vector<int> vec4( vec2 );
23. 迭代器对
迭代器对iterator pair 来标记向量的起始处和结束处。
vector 类模板提供了一对操作begin() 和end() ,它们分别返回指向向量开始处和结束处后1 个的迭代器。这一对迭代器合起来可以标记出待遍历元素的范围。
vector< int >::iterator iter = vec.begin();
for ( int ix = 0; iter != vec.end(); ++iter, ++ix )
*iter = ix;
24. C++向量泛型算
头文件#include <algorithm>
搜索(search )算法:find() 、find_if() 、search() 、binary_search()、 count()和count_if()
分类排序(sorting )与通用排序(ordering )算法:sort()、 partial_sort()、 merge() 、 partition() 、rotate() 、reverse() 和random_shuffle()
删除(deletion) 算法:unique() 和remove()
算术(numeric) 算法:accumulate() 、partial_sum() 、inner_product()、和adjacent_ difference()
生成(generation) 和变异(mutation) 算法:generate()、 fill() 、transformation() 、 copy() 和for_each()
关系(Relational) 算法:equal() min()和max()