//参考书:essental c++
第一章 c++编程基础
class:是用户自定的数据型别。
Class的定义,一般来说分为两部分,分别写于不同的文件:.h(声明该class所提供的各种操作行为)和.cpp(实现内容)。
Namespace:是一种将程序库名称封装起来的方法。避免和应用程序发生命名冲突。
Using namespace std:让命名空间中的名称曝光。
Template class机制使程序员得以直到是用template class时才决定真正的数据型别。
Container:Array与vector:
Vector是class template,必须在类名称之后的括号内指定元素型别,比如:
vector<int> vec(100),由于vector是一个类,所有有很多接口函数可以调用,并且vec是一个对象,有别于定义一个array。
Vector的初始化不同于array。
指针带来的弹性:
vector<int> *seq_addrs[6]={&fibonacci,&lucas,&pell,&triangular,&square,&pentagoanl};
由于[]的优先级高于*,所以seq_addrs是个array,其元素型别为vector<int> *,因袭seq_addrs[0]是fibonacci vector的地址。
vector<int> *current_vec=0;
current_vec=seq_addrs[i];//i是指标。current_vec就指向了所要指的地址。
rand()和srand():
srand()提供种子,rand()生成0到种子之间的随机数。
文件的读写:
#include <fstream>
//写
ofstream outfile("seq_data.txt",ios_base::app);
if(!outfile)
cerr<<......//cerr的输出没有缓冲
else
outfile<<...<<...;
//读
ifstream infile("seq_data.txt");
if(!infile)
...
else
infile>>...
//读写
fstream iofile("seq_data.txt",ios_base::in | ios_base::app);
if(!iofile)
...
else
iofile.seekg(0);//追加模式开启时,文件位置位于尾端,读时,要定位。
............
第2章 面向过程的编程风格
函数的组成:函数的返回型别,函数名称,函数的参数列表,函数主体.
函数的申明与定义.
如果函数的返回型别不为void,那么它必须在每个可能的退出点上将值返回.
参数传递方式:传值和传址
当我们调用一个函数时,会在内存中建立起一块特殊区域,称为"程序栈",这块特殊区域提供了每个函数参数的存储空间,它也提供函数所定义的每个对象的内存空间---我们将这些对象称为局部对象.一旦函数完成,这块内存就会被释放掉,或者说是从程序堆栈中被pop出来.
当以传值方式时,默认情形下其值会被复制一份,成为参数的局部性定义.和外部的对象没有关联.
传址有引用和指针两种方式.
当我们以by reference方式传递对象当做函数参数,对象本身并不会复制出另一份,复制的是对象的地址,函数中对该对象进行的任何操作,都相当于是对传入的对象进行间接操作.
把参数声明为热ference的理由是:希望得以直接对所传入的对象进行修改,为了降低复制大型对象的负担.
传pointer的效果和reference的效果相同:传递的是对象地址,而不是整个对象的复制品,唯一的差别在于用法不同。
生存空间(scope)及生存范围(extent)
除static定义的对象外,函数内定义的对象,只存活于函数执行之际。如果将这些所谓局部对象的地址返回,会导致执行期错误。如果以传值方式返回,返回的乃是对象的复制品,它在函数之外依然存在。
生存空间指对象在程序内的存活区域,生存范围指存活期。
动态内存管理:堆内存
new 和 delete
默认参数:默认值的决议操作由最右边开始进行;默认值只能够指定一次,可以在函数声明处,亦可以在函数定义处,但不能在两个地方都指定。但通常放在声明处。
局部静态对象;局部静态对象所处的内存空间,即使在不同的函数调用过程中,依然持续存在。
inline函数:将函数声明为inline,表示要求编译器在每个函数调用点上,将函数的内容展开。这使我们获得效率上的改善。
inline函数的定义常常被置于头文件中。
函数重载:
参数表不相同的拥有相同函数名称的函数。
模板函数(Template Functions):
函数模板将参数表中指定的所有或部分参数的型别信息抽离出来。比如:
template <typename elemType>
void display_message(const string &msg, const vector<elemType> &vec)
{}
使用时:
vector<int> ivec;
string msg;
display_message(msg, ivec);
此时,编译器会将elemType绑定位int型别,然后产生一份display_message()函数实体。
函数指针:必须指明其所指向之函数的返回值类型及参数表。比如:
cosnt vector<int>* (*seq_ptr)(int);
congst vector<int> *pseq=seq_ptr(pos);
const vector<int>* (*seq_array[])(int)={
fibon_seq,lucas_seq,pell_seq,
triang_seq,square_seq,pent_seq
};
第3章 泛型编程风格
STL由两种组件构成:容器和操作这些容器类的所谓泛型算法。
序列式容器:vector list
关联式容器:map set
泛型算法通过函授模板技术,达成“与操作对象之型别相互独立”的目的。
泛型指针:Iterators
.........
.........
序列式容器:
序列式容器用来维护一组排列有序、型别相同的元素,其中有第一、第二...一次类推,乃至最后一个元素。vector和list
是两个最主要的序列式容器。vector以一块连续内存来存放元素。list系以双向链接来存储内容,而非连续内存。
第三种序列容器是所谓的deque。
map:
map被定义为一对数值,其中的key通常是个字符串,扮演索引的角色,另一个数值是value。
set:
set由一群keys组和而成。如果我们想知道某值是否存在于某个集合内,就可以使用set。
第4章 给予对象的编程风格
Class由两部分组成:一组公开的操作函数和运算符(成员函数),以及一组私有的实现细节。
什么是构造函数和析构函数?以及拷贝构造函数
何谓mutable和const?
形参是const,保证在函数体内不被修改。
成员函数标注const,并且要在声明和定义中同时指定,不能修改成员变量。比如:
Class triangular{
Public:
Int len() const {return _len;}//const告诉编译器不会修改对象的内容
};
然而,用mutable申明的成员变量可以被声明为const的成员函数修改。对mutable变量所做的改变不会破坏类对象的常数性。
什么是this指针?
指向对象自己。
static class member,静态类成员
用来表示唯一一份可共享的成员,可以在同型的所有对象中被存取。对类而言,静态类成员只有唯一一份实体,必须在程序代码文件中提供定义,比如:
Vector<int> triangular::_elems;//置于.cpp文件中,不同于全局变量。
可以指定初始值,比如:int triangular::_elems=8;
Static member function静态成员函数
一般情形下,成员函数必须通过其类的某个对象调用,这个对象会被绑定致该成员函数的this指针。通过this指针才能存取存储于每个对象中的非静态成员变量。
静态成员函数在“与任何对象都无瓜葛”的情形下被调用。比如:
声明:class Triangular{
Static bool is_elem(int);
}
调用:(Triangular::is_elem(8))
静态成员变量和静态成员函数的关键字在实现时不需要重复加上static关键字。
运算符重载:
Copy assignment operator:
(未完待续。。。)