好久没写代码了,很多东西都忘记了。复盘一下
C++编写基础
头文件 与 输入 输出
#include<iostream>
using namespace std;
cout<<"Hello world!";
cin>>use_name;
运算符优先级
逻辑运算符 NOT
算术运算符 * / %
算术运算符 + -
关系运算符 > < <= >=
关系运算符 == !=
逻辑运算符 AND
逻辑运算符 OR
赋值运算符
如何使用Array和Vector
vector,可储存18个元素,每个元素的初始值为0;
#include<vector>
const int seq_siz = 18;
vector<int> pell_seq(seq_size);
文件的读写
#include<fstream>
//供输出的文件
ofstream outfile("seq_data.txt");//如果该文件不存在就新建一个文件以供使用
ofstream outfile("seq_data.txt",ios_base::app);
//如果文件已经存在且我们不希望丢弃原来的内容,而是希望将新数据增加到该文件中
//以追加模式打开该文件
if(!outfile) //检查文件是否成功打开
//共读取的文件
ifstream infile("seq_data.txt");
面向对象的编程风格
引用
int ival = 1024;
int &rval = ival;//reference(引用),代表一个int对象
int jval = 4096;
rval = jval;//就是将rval也就是ival设置为了4096;
//无法令rval转而代表jval,必须从一而终
//当我们以by reference方式将对象作为函数参数传入时,对象本身并不会复制出另一份--复制的是
//对象的地址
//pointer可能并没有指向某个实际对象,所以使用前需要检查
//而引用则必定会代表某个对象
作用域以及范围
除了static这个例外以外,函数内定义的对象只存在于函数执行期间。
如果要返回所谓局部对象的地址返回,会导致运行时错误
动态内存管理
new Type;
int *pi;
pi = new int(1024);
delete pi;
delete [] pi;//删除数组中的所有对象
提供默认参数值
void bubble_sort(vector<int> &vec,ofstream *ofil = 0);
//给*0fil提供了一个默认参数0
//默认值的解析操作由最右边开始执行,意思就是,一个带有默认参数的参数,它右边的所有参数必须也由默认参数
//默认值只能指定一次
//为了高可见性,有时会将默认值放在函数声明中,包含在头文件里
void display(const vector<int>&,ostream&=cout);
//而在函数定义处,并没有指定参数的默认值
使用局部静态对象
const vector<int>* fibon_seq(int size)
{
static vector<int> elems;
//函数的工作逻辑放在此处
return &elems;
}
elems被定义为fibon_seq()函数中的局部静态对象,该对象的存在不会因为函数的调用和结束而重新建立和破坏
提供重载函数
void display_message(char ch);
void display_message(const string&, int);
//编译器无法根据函数返回类型来区分两个具体相同名称的函数
定义并使用一个模板函数
function template(函数模板)
将参数列表中指定的全部(或部分)参数的类型信息抽离出来
template <typename elemType>
void display_message(const string &msg,const vector<elemType> &vec)
{
cout<<msg;
for(int ix = 0;ix < vec.size();++ix)
{
elemType t = vec[ix];
cout<<t<<'';
}
}
标识符起到占位符的作用,用来放置函数参数列表及函数体中的某些实际数据类型
如何使用函数模板:
vector<int> ivec;
string mag;
//...
display_message(msg,ivec);
编辑器会将elemType绑定为int类型,然后产生一份display_message()函数实例,于是其第二参数的类型就变成了vector<int>,函数体内部的局部对象类型也变成了int
函数指针带来更大的弹性
const vector<int>* (*seq_ptr)(int);
bool seq_elem(int pos,int &elem,const vector<int>* (*seq_ptr)(int))
{
//调用seq_ptr所指的函数
const vector<int>*pesq = seq_ptr(pos);
if(!pesq)
{elem = 0;return false;}
elem = (*pseq)[pos - 1];
return true;
}
//提供函数的名字就可以将函数的地址交给指针
//将pell_seq()的地址赋值给seq_ptr
seq_ptr = pell_seq;
设定头文件
头文件命名 后缀名.h
函数的定义只能有一份,声明可以有多份,不把函数的声明放入头文件,因为同一个程序的多个代码文件可能都会包含这个头文件
//这是可以放在头文件中的一份声明
extern const vector<int>* (*seq_array[seq_cnt])(int);
//这会被视为定义
const vector<int>* (*seq_array[seq_cnt])(int);
泛型编程风格
STL
容器:vector list set map等类
泛型算法:find(), sort(), replace(), merge() 等
迭代器iterator: first last
每个标准容器都提供一个名为begin()的操作函数,可返回一个iterator,指向第一个元素,另一个名为end()的操作函数会返回指向最后元素的下一位置的iterator
了解Iterator(泛型指针)
基于对象的编程风格
class Stack
{
public:
//...public接口
private:
//...private实现部分
}
所有的member function都必须在class主体内进行声明,定义可以在类体外,如果定义在类体内,这个member function会自动被视为inline函数
//类体外定义函数,如果希望是inline函数,要使用inline关键字
inline bool Stack::empty()
{...}
bool Stack pop()
{...}
//Stack:: 这两个冒号就是所谓的class scpoe resolution (类作用域解析)运算符
构造函数与析构函数
//构造函数的名称必须与类名相同,不需要返回值,可以被重载
class Triangular{
public:
Triangular();//default constructors
Triangular(int len);
Triangular(int len,int beg_pos);
//...
}
Triangular t3 = 8;//调用第二个构造函数
成员初始化列表 Member initialization List
Triangular::Triangular(const Triangular &rhs)
:_length (rhs._length),_beg_pos(rhs._beg_pos),
_next(rhs._beg_pos-1) //不要在这里写分号 ;
{} //空的
析构函数
//名称:class的名称再加一个~,没有返回值,也没有任何参数,所以也不会被重载
//一旦某个class提供有destrustor,当其object结束生命时,便会自动调用destructor处理善后
//destructor主要用来释放在constructor中或对象生命周期中分配的资源
class Matrix{
public:
...
~Matrix()
{
delete [] _pmat;
}
}