Essential C++复习笔记(1)

好久没写代码了,很多东西都忘记了。复盘一下

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;
  }
}

mutable(可变)和 const(不变)

猜你喜欢

转载自blog.csdn.net/zaizai1007/article/details/129695844