c++------essentialc++

伪随机数

rand()和srand()都是标准库提供的伪随机数生成器,srand()的参数是随机数生成器种子
声明在cstdlib头文件中

文件读写

首先包含fstream头文件#include<fstream>
为了打开一个供输出的文件,定义一个ofstream对象ofstream outfile(path,mode);
(指定路径的文件不存在,会被创建出来。如果文件未能打开,ofstream对象的求值结果为false)
cerr代表标准错误设备,cerr<<"出错";和cout一样,cerr将输出结果定向到用户的终端,cerr的输出结果无缓冲,会立即显示在用户终端

如果打开一个供读取的文件,定义一个ifstream对象,如果文件 没有成功打开,该ifstream对象结果为false.如果成功,该文件的写入位置设定在起始处。

如果想要同时读写同一个文件,定义一个fstream对象。

fstream iofile("a.txt", ios_base::in|ios_base::app);

以追加模式打开文件,文件位置会位于末尾,seekg()可以将iofile重新定位至文件的起始处,如iofile.seekg(0);

终止程序

#include<cstdlib>
exit(-1);

函数

如果函数体的最后一个语句不是return ,那么最后一条语句之后就是该函数的隐式退出点。
函数的默认参数值

  1. 默认值的解析从最右边开始继续进行,如果为某个参数提供默认值,该参数右侧的所有参数都必须有默认参数值
  2. 默认值只能够指定一次,在函数声明(推荐)或者函数定义,但不能两个地方都指定
    局部静态对象
    在函数内定义的静态对象,局部静态对象所处的内存空间,即使在不同的函数调用过程,依然存在。

inline函数
将函数声明为inline,表示要求编译器在每个函数调用点上,将函数的内容展开。
在函数前面加上关键字inline。inline函数的定义,通常被放在头文件中。

函数重载
参数列表不相同(参数类型不同,参数个数不同)

函数模板
template<typename elemType>这里elemType是一个占位符
函数模板的参数列表通常由两种类型构成,一类是明确的类型,另一类是暂缓决定的类型
函数模板也可以进行重载

函数指针
type (*func)();
枚举类型enum
enum num_type{};列表里面的每一项是枚举类,默认情况下第一个枚举类是0,依次后排,也可以特定指定值。

头文件

头文件的扩展名,一般是.h。标准库没有扩展名。
函数的定义只能有一份,但可以有多份声明。
inline函数的定义必须放在头文件中,不能放在不同的程序文件中。
如果可能被多个文件访问,就应该被声明于头文件中。
就像函数一样,一个对象只能在程序中被定义一次。


STL

STL由两种组件构成,一个是容器,一个是泛型算法。
vector,list是顺序性容器
map,set属于关联容器

泛型算法提供作用于容器类及数组类型上的操作(泛型:它们和它们想要操作的元素类型无关)

泛型指针
每个标准容器都提供一个begin()函数,返回一个iterator指向第一个元素。另一个end()函数返回一个iterator,指向最后一个元素的下一个位置
一般是::iterator,面对const 对象,使用::const_iterator

所有容器(及string类)的共通操作
==或!=
=运算符
empty()
size()
clear()
除此之外,还提供通用插入函数insert()插入元素,通用删除函数erase()删除元素
erase()函数返回的iterator,指向被删除的最后一个元素的下一个位置

顺序性容器

顺序性容器用来维护一组排列有序,类型相同的元素。
vector用一块连续内存存放元素,于是可以随机访问。vector内的每个元素被存储子啊距离起始点的固定偏移位置上。

list以双向链接存储内容,可以执行前进或后退操作。
list的每个元素包括三个字段:value,back指针,front指针。不能随机访问。
list不支持iterator的偏移计算,如iterator+num

deque,以连续内存存储元素。标准库的queue就是以deque实现的,以deque作为底部存储元素。
使用顺序性容器

#include<vector>
#include<list>
#include<deque>

定义容器对象:
1.vector ivec;
2.vector svec(32);
3.vector ivec(10,-1);
4.int a[8]={1,2,3,4,5,6,7,8}; vector fib(a, a+8);
5.list slist; list slist2(slist);

在容器末尾进行插入和删除操作:push_back()和pop_back()
list和deque还提供了push_front()和pop_front()
注意,pop_back()和pop_front()这两个操作函数不会返回被删除的元素值

function object

function object是某种class的实例对象。这类class对function call运算符做重载操作,使得function object当成一般函数使用
令call运算符成为inline,消除“通过函数指针来调用函数”付出的额外代价

#include<functional>

function object adapter
binder adapter(绑定适配器)会将functionobject的参数绑定到特定值,使得二元function object转化为一元function object
标准库提供两个binder adapter:bind1st将指定值绑定到第一操作数,bind2nd将指定值绑定到第二操作数

另一种adapter是negator,对function object的真伪值取反,其中not1对一元function object的真伪值取反,not2对二元function object的真伪值取反。

function object是一种“提供有function call运算符”的class。
形如bool operator()(int _value) const;

map

map定义为一对数值map<string,int> words;
map对象有一个名为first的member,对应于key.一个名为second的member,对应于value
查询时,若一个索引的key不存在在map中,使用key后这个key会自动被加入map中
任何一个key值在map内最多只会有一份。如果需要存储多份相同的key值,使用multimap

set

set由一群key组合而成。对于任何key值,set只能存储一份。如果要存储多份相同的key值,必须使用multiset。
默认情况下,set元素依据所属类型默认的less-than运算符进行排序(从小到大)

标准库提供三个insertion adapter

#include<iterator>

back_inserter(容器)以容器的push_back()函数取代assignment运算符,vector合适
inserter(容器,iterator)以容器的insert()函数取代assignment运算符,vector合适
front_inserter()以容器的push_front()函数取代assignment运算符,只适合list和deque

iostream iterator

标准库定义供输入和输出使用的iostream iterator类,为istream_iterator和ostream_iterator分别支持单一类型的元素读取和写入。

#include<iterator>

利用istream_iterator从标准输入设备读取字符串
istream_iterator<string> is(cin);提供了一个first iterator,将is定义为“绑定标准输入设备”的istream_iterator。
对于标准输入设备来说,end-of-file代表last。
只要在定义istream_iterator时不指定istream对象,就代表了end-of-file。即istream_iterator<string> eof;
而ostream_iterator标示字符串元素的输出位置。ostream_iterator os(cout, " ");表示os定义为一个“绑定标准输出设备”的ostream_iterator。

#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;

int main() {
	istream_iterator<string> is(cin);
	istream_iterator<string> eof;

	vector<string> text;
	copy(is, eof, back_inserter(text));

	sort(text.begin(), text.end());

	ostream_iterator<string> os(cout, " ");
	copy(text.begin(), text.end(), os);
}

从文件中读取,写到文件中去

#include<iostream>
#include<fstream>
#include<iterator>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;

int main() {
	ifstream in_file("input_file.txt");
	ofstream out_file("out_file.txt");

	if (!in_file || !out_file) {
		cerr << "unable to open the file.\n";
		return -1;
	}

	istream_iterator<string> is(in_file);
	istream_iterator<string> eof;

	vector<string> text;
	copy(is, eof, back_inserter(text));

	sort(text.begin(), text.end());

	ostream_iterator<string> os(out_file, " ");
	copy(text.begin(), text.end(), os);
}

class

一般,class由两部分组成:一组public操作函数和运算符,一组private实现细节。
成员函数必须在class主体内进行声明,如果在主体内定义,这个成员函数会自动被视为inline函数。

class定义及inline member function通常都会被放在与class同名的头文件中。而之外的非inline成员函数在程序文件中定义,该文件通常和class同名。

构造函数

构造函数的函数名称必须与class名称相同,且不能指定返回类型和返回任何值(可以被重载)。

成员初始化列表
成员初始化列表紧接在参数列表最后的冒号后面,以逗号分隔的列表。
classname::classname():num_1(num1),num_2(num2){}

析构函数

当一个类对象结束时,自动调用析构函数处理释放在构造函数或者对象生命周期中分配的资源。
class名称加上“~”前缀,不会有返回值,也没有任何参数。由于参数列表为空,也不可能被重载。

在成员函数 函数参数列表后面函数体前面添加const,表示该函数不会改变传入的类对象的值。
凡是在class主体之外定义的const成员函数,必须同时在声明和定义中指定const。

关键字mutable
在类内变量添加mutable,不视为改变类对象的状态或者说不算破坏对象的常量性

this指针

this指针在成员函数内部指向该调用对象。

静态类成员

static数据成员用来表示唯一的,可共享的成员,可以在同一个类的所有对象中被访问。
成员函数只有在“不访问任何non-static member”的条件下才能够被声明为static,在函数声明之前加上关键字static(定义的时候不用重复添加)

自定义运算符
bool operator==(const classname&) const;

任何运算符如果和另一个运算符性质相反,可以以后者实现前者。
运算符函数的参数列表中,必须至少有一个参数为class类型

运算符的定义方式:像成员函数一样,像非成员函数一样
非成员运算符的参数列表中一定比相应的成员运算符多一个参数,即this指针。

递增运算符前置和后置版本。后置版本的参数列表不能为空,额外加入一个int参数用来与前置版本进行区别。

类型设定typedef
typedef existing_type new_name;

关键字friend

friend具备和类成员函数相同的访问权限,可以访问class的private成员。
在声明时,在函数前加上friend,这个声明可以出现在class定义的任意位置上,不受private和public的影响。

类也可以声明为friend。

重载iostream运算符

ostream& operator<<(ostream &os, const classname &rhs)
1.其中ostream对象未声明为const,因为每个output操作都会更改ostream对象的内部状态。
2.output运算符不能设计为成员函数,如果作为一个成员函数,左边操作数必须属于同一个class对象。
istream& operator>>(istream &is, classname &rhs)

指向类成员函数的指针

例如:void (num_sequence::*pm)(int) =0;
其中pm=0表示它目前并不指向任何成员函数。
使用typedef简化:

typedef void(num_sequence::*PtrType)(int);
PtrType pm = 0;
PtrType pm = &num_sequence::fibonacci;

面向对象

两个最主要的特质:继承和多态

在c++中,父类被称为基类,子类被称为派生类。父类和子类之间的关系称为继承关系。

抽象基类
静态绑定在编译时,程序执行之前就已经解析出。
动态绑定解析操作延迟到运行时才进行。

虚函数virtual
默认情况下,成员函数的解析都在编译时,若令其在运行时动态进行,在声明前加上关键字virtual(定义时不用加)。
static成员函数无法被声明为虚函数


将虚函数赋值为0,令它为一个纯虚函数。任何类如果声明多个纯虚函数,由于接口的不完整性(纯虚函数没有函数定义),程序无法为它产生任何对象。这种类只能作为派生类的子对象使用,前提时这些派生类必须为所有虚函数提供确切的定义。


凡基类定义有一个或多个虚函数,则析构函数声明为virtual

如果派生类继承了纯虚函数,那么这个派生类也会被视为抽象类,无法为它定义任何对象。如果要覆盖基类提供的虚函数,那么派生类提供的新定义,其函数原型必须完全符合基类声明的函数原型(参数列表、返回值、常量性)
返回类型不同有例外: 当基类的虚函数返回某个基类形式(通常时pointer或reference),这种情况下派生类的同名函数可以返回该派生类的类型
------------------------------------------------------------------》在派生类中,为了覆盖基类的某个虚函数,在进行声明操作时,不一定要加上关键字virtual。

虚函数机制不会出现预期效果

  1. 基类的构造函数和析构函数内
  2. 使用基类的对象,而不是基类对象的指针或者引用

在基类的构造函数中,派生类的虚函数绝对不会被调用。
当为基类声明一个实际对象,同时也就是分配了容纳该实际对象的内存空间。如果传入的是个派生类对象,就没有足够的空间放置派生类中的非基类内容。


当程序定义出一个派生对象,基类和派生类的构造函数都会被执行(对应的是,当派生对象被销毁时,基类和派生类的析构函数都会被执行,按照栈进栈出的方式

关键字protected
被声明为protected的所有成员都可以被派生类直接访问。

类进行继承声明之前,其基类的定义必须已经存在。
当派生类的某个成员和基类的成员同名时,便会掩盖基类的那个成员。如果要Z在派生类内使用继承基类的那个成员,必须利用class scope运算符加以限定。

运行时类型鉴定机制

typeid运算符#include<typeinfo>
typeid运算符会返回一个type_info对象,存储与类型相关的信息。
用途1: 可以通过比较类信息来确定两个对象是不是属于同一个类。

template

template <typename Type>
class BinaryTree;

Binarytree<int> bt;

为了通过类模板实例化类,在类名后添加<实际Type>取代。
一般情况下,模板类型包含在参数列表都在类模板和其成员定义中。

将所有的template类型参数视为“class类型”处理。声明为一个const reference并非by value方式传递。在成员初始化列表内对类型参数进行初始化
例如:template <typename valType> inline BTnode<valType>::BTnode(const valType &val) : _val (val){}
在这里插入图片描述在这里插入图片描述
将指针声明为引用指针,这样不仅可以改变指针本身,也可以改变指针指向的对象。

在这里插入图片描述

以表达式作为template参数

在这里插入图片描述在这里插入图片描述在这里插入图片描述成员函数也可以定义成模板形式------》致只写一份函数定义
类模板内也可以定义成员函数模板

异常处理机制

异常的鉴定与发出,异常的处理方式
throw表达式抛出异常
catch子句捕获被抛出的异常,组成:关键字catch、小括号内的类型或对象、大括号内的语句(处理异常)


有时候我们可能无法完成异常的完整处理,在记录信息之外,需要重新抛出异常,寻求其他catch子句的协助。
重新抛出时,只需写下throw。它只能出现在catch子句中,将捕获的异常对象再一次抛出,并由另一个类型符合的catch子句处理。

如果想要捕获任何类型的异常,使用一网打尽的方法,只要在异常声明的部分指定省略号(…)

catch(...){

}

catch子句是和try块一起的,catch子句放在try块的末尾,如果try块内有异常发生,由接下来的catch子句加以处理。

局部资源管理

分配资源
处理
释放资源

如果处理时抛出异常,那么释放资源就不会发生
处理方法:定义一个类
在异常处理机制终结某个函数之前,可以保证函数中的所有局部对象的析构函数都会被调用。

在这里插入图片描述
auto_ptr时标准库提供的类模板,会自动删除通过new表达式分配的对象
包含头文件:#include<memory>
auto_ptr还将解引用和箭头运算符重载,可以像使用一般指针一样使用auto_ptr对象。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值