读书笔记之:C++Primer 第3版

C++ Primer v3

前两天看完了《C++ primer》的第4版,今天刚看完第3版。第3版看得比较粗略。总的感觉是第4版显得比较条理,第3版的细节比较分散。第4版中将很多应该注意的知识点都重点强调了一下,从第3版不好区分哪些比较重点。

第一章 C++概述
1. 编译C++程序时,编译器自动定义了一个预处理器名字__cplusplus.
在编译标准C时,编译器自动定义宏__STDC__。当然,__cplusplus和__STDC__不能被同时定义
第二章 C++浏览
1. C++中的数组
在内置数据类型与标准库类的类型之间是复合类型(compound type)特别是指针和数组,引用类型。
虽然C++对数组提供了内置支持,但是这种支持仅限于“用来读写单个元素”的机制,C++不支持数组的抽象(abstraction),也不支持对整个数组的操作。
数组类型本身没有自我意识,它不知道自己的长度,我们必须另外记录数组本身的这些信息。在C++中,数组不同于整数类型和浮点数类型,它不是C++语言的一等(first-class)公民。数组是从C语言继承过来的,它反映了数据与其进行操作的算法的分离,而这正是过程化程序设计的特征。
2. 静态与动态内存分配
(1)静态对象是有名字的变量,可以直接对其进行操作。而动态对象是没有名字的变量,我们只能通过指针对其进行间接操作。
(2)静态对象的分配与释放是由编译器自动处理的。相反动态对象的分配与释放必须由程序员显式地管理。
内存泄露(memory leak)是指一块动态分配的内存,我们不再拥有指向这块内存 的指针,因此我们没有办法将它返还给程序供以后重新使用。

第3章 C++数据类型
1. 常用的转义字符

backspace(退格键) \b

carriage return (回车键) \r

alert (beel) (响铃符) \a

single quote (单引号) \'

horizontal tab(水平制表键) \t

newline(换行符) \n

backslash (反斜杠键) \\

double quote (双引号) \"

vertical tab(垂直制表键) \v

formfeed (进纸键) \f

question mark (问号) \?

 


 

 

 

 

 

 2. 变量

什么是变量?变量是程序的静态存储区域中的一块内存区域的名字。
变量和文字常量都有存储区域,并且也有相关的类型。区别在于变量是可寻址的。
对于每一个变量,都有两个值与其关联:
(1)它的数值(右值,只能读取)(2)它的地址(左值,可以被赋值)
3. 关键字
c89中有32个关键字,C99添加5个

auto 1

else enum extern 3

register return 2

void volatile 2

break 1

float for 2

short signed sizeof static struct switch 6

while 1

case char const continue 4

goto 1

typedef 1

inline restrict _Bool _Complex _Imaginary 5

default do double 3

if int long 3

union unsigned 2

 

C++中的关键字(63)

asm auto 2

false float for friend 4

namespace new 2

template this throw ture try typedef typeid typename 8

bool break 2

goto 1

operator 1

union unsigned using 3

case catch char class const const_cast continue 7

if inline int 3

private protected public 3

virtual void volatile 3

default delete do double dynamice_cast 5

long 1

register reinterpret_cast return 3

wchar_t while 2

else enum explicit export extern 5

mutable 1

short signed sizeof static static_cast struct switch 7

操作符替代名(11)
and and_eq, bitand bitor, compl, not not_eq, or or_eq, xor xor_eq

 4. const限定符

一般编译器不能跟踪指针在程序中任意一点指向的对象。(这种内部工作需要根据数据流分析(data flow analysis),通常由单独的优化器(optimizer)组件来完成)
5. 枚举类型
enum MODE{IN,OUT,APPEND}
我们不能使用枚举成员进行迭代:
//wrong
for ( open_modes iter = input; iter != append; ++iter )
// ...
C++不支持在枚举成员之间前后移动
我们可以定义枚举类型的对象,并且我们只能够使用相同枚举类型的对象或枚举成员来进行初始化。
但是,在必要时,枚举类型会自动被提升为算术类型。
如:
const int array_size = 1024;
// ok: pt2w 被提升成 int 类型
int chunk_size = array_size * pt2w;

第4章 表达式
1. 算术异常
算术异常主要归咎于算术的自然本质(比如除以0)或归咎于计算机的自然本质(比如溢出)

第7章
1. 缺省实参
函数调用的实参按位置解析,缺省实参只能用来替换函数调用缺少的尾部实参。
函数声明可以为全部或部分参数指定缺省实参。在左边参数的任何缺省实参被提供之前,最右边未初始化参数必须被提供缺省实参。这是由于函数调用的实参是按照位置解析的。

一个参数只能在一个文件中被指定一次缺省实参。
习惯上,缺省实参在公共头文件包含的函数声明中指定,而不是在函数定义中。如果缺省实参在函数定义的参数表中提供,则缺省实参只能用在包含该函数定义的文本文件的函数调用中。
函数后继的声明中可以指定其他缺省实参——一种对特定应用定制通用函数的有用方法。
【1】


2. 返回值
C++中,如果函数返回一个左值,那么对返回值的任何修改都将改变被返回的实际对象。
为了防止对返回值的无意修改,返回值应该被声明为const:
const int &get_val(...)
3. 函数指针
当一个函数名没有被调用操作符修饰时,会被解释成指向该类型函数的指针。
将取地址操作符作用在函数名上也能产生指向该函数类型的指针。
利用函数指针调用函数时,不需要解引用操作符。无论是用函数名直接调用函数,还是用指针间接调用函数,两者的写法都是一致的。
4. 指向extern “C“函数的指针
指向C函数的指针与指向C++函数的指针类型不同。所以如果用指向C++函数指针去为指向C函数的指针来进行赋值或初始化的话会产生编译错误。
如:
extern "C" void (*pf1)(int);
void(*pf2)(int);
pf1=pf2;//error
当链接指示符应用在一个声明上的时候,所有被它声明的函数都将受到链接指示符的影响。
如:
// pfParm 是一个指向 C 函数的指针
extern "C" void f1( void(*pfParm)(int) );

第8章 域和生命期
1.类型安全机制(type-safe-linkage)
在c++中,有一种机制,通过它可以把函数参数的类型和数目编码在函数名中,叫做类型安全链接(type-safe linkage)。类型安全链接可以用来帮助捕捉不同文件中函数声明不匹配的情况。
不同文件中出现的同一对象或函数声明的其他类型不匹配情况,在编译或链接时可能不会被捕捉到.因为编译器一次只能处理一个文件,它不能很容易地检查到文件之间的类型违
例.这些类型违例可能是程序严重错误的根源.例如, 文件之间错误的对象声明或函数返问类型就不能被检测出来.这样的错误只能在运行时刻异常或程序的错误输出中才能被揭示出
来.
2. 常量折叠(constant folding)
常量折叠(Constant folding)是其中一种被很多现代编译器使用的编译器最优化技术。常量折叠是在编译时间简单化常量表达的一个过程。简单来说就是将常量表达式计算求值,并用求得的值来替换表达式,放入常量表。可以算作一种编译优化。
例如
const int i=100;
const int j=i+10;

在编译时并没有给i和j 分配存储空间,也就是说遇到i就用100代替,编译同时也进行了简单的常量计算,所以遇见j就用110代替,这样i和j就不占用内存了。若是要做取地址操作,比如:long address =(long)&j; 这就需要为常量j分配内存空间了,但其值是不可改变的。
编译器会为常量分配了地址,但是在使用常量的时,常量会被一立即数替换(保护常量,防止被破坏性修改)
3. 动态内存分配
【2】

4. 定位new表达式
【3】

5. 显示调用析构函数
1。显式调用的时候,析构函数相当于的一个普通的成员函数
2。编译器隐式调用析构函数,如分配了对内存,显式调用析构的话引起重复释放堆内存的异常
3。把一个对象看作占用了部分栈内存,占用了部分堆内存(如果申请了的话),这样便于理解这个问题
系统隐式调用析构函数的时候,会加入释放栈内存的动作(而堆内存则由用户手工的释放)
用户显式调用析构函数的时候,只是单纯执行析构函数内的语句,不会释放栈内存,摧毁对象

第9章 函数重载
1. extern "C" 与函数重载
【4】

2. 类型安全链接
【5】

3. 参数类型转换
【9】
【8】
【6】

显示类型转换:
强制转换 (类型名)表达式
函数法 类型名(表达式)
单参数的构造函数具有将参数类型转换为该类类型的功能。
定义类类型转换函数:
operator 目的类型();

第10章 函数模板
1.函数模板的定义
如果在全局域中声明了与模板参数同名的对象、函数或类型,则该全局名将被隐藏。
函数模板定义中声明的对象或类型不能与模板参数同名。
【10】

如同非模板函数一样,函数模板也可以被声明为inline和extern,注意,应该把指示符放在函数模板参数表后面,而不是关键字template前面。

2. 函数模板的实例化
函数模板在它被调用或取其地址时被实例化。
3. 显示模板实参
使用显示模板实参的两种情况:
(1)无法推断出正确的函数调用,调用是模棱两可。
(2)当编译器无法推演出函数的返回类型的时候。

第13章 类
1. 类的定义与声明
因为只有当一个类的类体已经完整时,它才被视为已经被定义,所以一个类不能有自身类型的数据成员.但是,当一个类的类头被看到时,它就被视为已经被声明了,所以一个类可以用>
指向自身类型的指针或引用作为数据成员.
2. const成员函数
const成员函数只能被const类对象调用。对于在类体外定义的const成员函数,我们必须在它的定义和声明中同时指定关键字const。
构造函数和析构函数即使不是const成员函数,const类对象也可以调用他们。当构造函数执行结束,类对象已经被初始化时,类对象的常量性就被建立起来了.析构函数一被调用,常量性就消失.所以一个const类对象"从构造完成时刻到析构开始时刻"这段时间内被认为是const 。
所以说,const类对象和非const类对象具有使用相同的构造函数和析构函数。3. volatile 成员函数
也可以将成员函数声明为volatile.如果一个类对象的值可能被修改的方式是编译器无法控制或检测的,则把它声明为volatile.与const类对象类似,对于一个volatile类对象,只有volatile成员函数,构造函数和析构函数可以被调用
4. mutable数据成员
【11】

5. 静态数据成员
【12】

6. 静态成员函数
静态成员函数的声明除了在类体中的函数声明前加上关键字static,以及不能声明为const或volatile之外,与非静态成员函数相同.出现在类体外的函数定义不能指定关键字static

静态成员函数没有 this 指针,因此在静态成员函数中隐式或显式地引用这个指针都将导致编译时刻错误。试图访问隐式引用 this 指针的非静态数据成员也会导致编译时刻错误。

第14章
1. 限制对象创建
【13】

2. 显示调用析构函数
在某些程序情况下,有必要显示地对一个特殊类对象调用析构函数。
这常常发生在和定位 new 操作符结合(placement operator new,见 8.4 节讨论)的时候

3. 内联析构函数
第15章 重载操作符和用户定义的转换
1. 重载操作符
【14】
【18】

第16章 类模板
1. 类模板定义
【15】

第17章 类继承和子类型
【16】

2. C++对多态的支持
多态性指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。C++支持两种多态性:编译时多态性,运行时多态性。
(1).编译时多态性:静态联编,通过重载函数实现;
(2).运行时多态性:动态联编,通过虚函数实现。虚函数改变了联编方式。
将成员函数声明为虚函数相当于告诉编译程序:由指针实际指向的对象类型决定调用哪个类中定义的函数
虚函数声明只出现在类声明中的函数原型中,而不能在成员的函数体实现的时候;
3. 虚析构函数
[19]

在继承机制下的析构函数的行为如下:派生类的析构函数先被调用。
4. 纯虚函数与抽象类
纯虚函数是一种特殊的虚函数,它仅起到为派生类提供一个一致接口的作用
抽象类只能作为基类来派生新类,不能说明抽象类的对象,但可以说明指向抽象类对象的指针;
5. 虚函数的静态调用
当用类域操作符调用虚拟函数时,我们改变了虚拟机制,使得虚拟函数在编译时刻被静态解析。
为什么要这样做呢?这样是为了效率!在一个派生类中,常常需要调用基类的实例来完成“已经在基类和派生类实例间被抽取出来的操作”。  
6. 虚函数与缺省实参
虚函数的缺省实参不是在运行时刻决定的,而是在编译时刻根据被调用函数对象的类型决定的。



 

 

posted @ 2012-03-10 18:17  Mr.Rico  阅读(377)  评论(0编辑  收藏  举报