c++ 学习笔记

IO 库

  • istrream(输入流)类型, 提供输入操作。
  • ostream(输出流)类型,提供输出操作。
  • cin, 一个istream对象,从标准输入读取数据。
  • cout,一个ostream对象,向标准输出写入。
  • cerr,一个ostream对象,通常用于输出程序错误信息,写入标准错误。
  • ">>运算符,从istream对象读取写入数据。
  • <<运算符,向ostream对象写入输出数据。
  • getline函数,从istream对象读取一行数据,写入给定的string类对象中。

io对象无拷贝或赋值

文件流(定义在fstream头文件中)

文件打开模式

ofstream out("file");                  //默认out模式打开文件会清空文件内容
ofstream out2("file", ofstream::out);  
//显式指定app模式会保留内容,在文件末尾执行操作
ofstream out3("file", ofstream::out | oftream::app); 

string流(定义在sstream中)

容器

迭代器

begin和cbegin函数之间的不同:cbegin函数为c++11新标准引入, 用来支持auto。cbegin返回const迭代器。过去只能显式的声明使用哪种迭代器,现在在调用begin时根据对象是否是常量对象来选择是否返回const类型的迭代器,而调用cbegin时无视容器类型返回const_iterator.
同一容器的两个迭代器可以表示一个范围

assign

可以用来对容器重新赋值,将右边运算对象的全部值拷贝至调用该函数的容器。

list<string> num;
vector<const char*> oldelm;
num = oldelm;   //错误:容器类型不同,无法赋值
num.assign(oldelm.begin(), oldelm.end());

swap

除string和array外,swap前后不改变容器的迭代器、引用和指针,皆指向swap之前的元素。
string的swap会导致这三者失效,而array会真正交换其中的元素。其交换时间与元素数目成正比

insert

insert返回指向插入元素的迭代器。

不同容器的迭代器不可比较
map中的key-value对应是pair类的元素

find和count

find返回所查找元素的迭代器,未找到时返回尾后迭代器。count返回要查找元素出现(可重复容器)的次数,
未找到时返回0.

有序容器的关键字类型

class A{
	int mem;
	//...
};
bool A::comp(A a,A b){
	return a.mem<b.mem;
}
multiset<A, decltype(comp)*>aset(comp); //这样就可以指定自定义的操作

insert的返回值

insert返回的值依赖容器的类型。对于不可重复的关联容器,insert返回一个pair,first为指向插入元素的迭代器,second为一个bool值,若容器中不存在该关键字返回true,存在则插入失败,返回false。

泛型算法

accumulate

type sum = accumulate(v.begin(), v.begin(), m)
accumulate对容器v的元素求和,和的初始值为m。执行的加法依据m的类型,所以m的类型非常关键。
vector<string> v; string sum = accumulate(v.begin(), v.end(), string("")); //正确 //错误, const string* 上未定义+运算符。 string sum = accumulate(v.begin(), v.end(), "");

list这类的特定容器算法

成员函数版本比通用版本性能更优。

lst.merge(lst2, comp); //合并两个有序列表,lst2会被清空
lst.merge(lst2);

lst.remove(val);
lst.remove_if(pred);

lst.sort();
lst.sort(comp);

lst.unique(); //删除连续相同元素,只保留其中一个
lst.unique(comp); //二元谓词

迭代器

back_inserter

插入迭代器,接受一个指向容器的引用,返回与该容器绑定的插入迭代器。具体效果是通过此迭代器赋值时,赋值运算符会调用push_back向容器中添加指定元素。

vector<int> vec;
fill_n(back_inserter(vec), 10, 0); //添加十个元素到容器中
iostream迭代器
istream_iterator<int> inp_it(cin);
istream_iterator<int> eof;
ifstream in("filename");
ostream_iterator out(cout, " ");  //每次输出后都会加上一个空格

可以通过inp_it和eof来遍历输入流对象。

unique

unique只会消除相邻近的重复元素。

vector<int> vec = {1,3,3,4,2,3,4,2,2};
unique(vec.begin(), vec.end()); //输出1,3,4,2,3,4,2
sort(vec.begin(), vec.end());   //先对容器内的元素排序
unique(vec.begin(), vec.end()); //再用unique就可以消除所有重复元素

lambda

一个lambda表达式表示一个可调用的代码单元。
可以通过尾置返回类型来指定lambda返回类型。
编译器在处理lambda表达式时,实际上是产生了一个未命名函数类的未命名对象,通过函数调用符来进行调用。

bind

每一个占位符“_n”使用前需要声明。
using std::placeholders::_1;
若果希望传递给bind一个对象(类似ostream)但又不想拷贝它,可以使用标准库ref函数。

动态内存

make_shared(智能指针)

shared_ptr<int> p= make_shared<int>(42);
shared_ptr<string> p2 = make_shared<string>(10, '9');
shared_ptr<int> p3 = make_shared<int>();
auto p4 = make_shared<vector<int>>();

不要用get来初始化另一个智能指针或为智能指针赋值

new

int *i = new int; // i指向一个动态分配的未初始化的无名对象
new在内存中创建一个未初始化的int对象,并返回指向该对象的指针。
默认情况下,动态分配的对象是默认初始化的,类类型的对象则调用该类的构造函数进行初始化,而内置类型和组合类型的对象的值是未定义的。
new创建过程的三步

  • 调用名为 operator new或operator new[]的标准库函数来分配足够大的空间
  • 对值进行初始化,如果创建的对象是类类型则会调用该类型的构造函数
  • 返回指向该对象的指针

括号包围的初始化器
auto i = new auto(obj) //i指向一个与obj类型相同的对象(用obj初始化)
动态分配的const对象
动态分配的常量必须在声明时就进行赋值或者初始化。
内存耗尽
int* p = new nothrow int(42);
当内存不足以分配出足够空间时,会抛出一个bad_alloc异常,而如果加上nothrow则不会抛出异常,而是返回一个空指针。

unique_ptr

给unique_ptr传递自定的删除器时需要在模板参数列表中加入删除器的指针,而shared_ptr则不用。具体如下:

void del(string&);
unique_ptr<string, decltype(del)*> up(new string, del);
shared_ptr<string> sp(new string, del);

weak_ptr

指向shared_ptr控制的对象,可以用来核查指向的对象是否还存在。

shared_ptr<string> s(new string);
weak_ptr<string> wp(s);
wp.use_count();       //返回共享该对象的智能指针数。
wp.expired();           //use_count()为零则为true,否则为false。
wp.lock();                //返回指向该对象的一个shared_ptr, 没有则返回空的shared_ptr.

动态数组

int *p = new int[10];
分配一个动态数组会返回一个元素类型的指针。
我们可以分配一个大小为零的动态数组,但不能解引用其返回指针。

allocate类

allocator<string> alloc;
auto const p = alloc.allocate(10);
auto q = p;
alloc,construct(q++);
alloc.construct(q++, "hi");
alloc.construct(q++, 10, 'c');
while(q!=p)alloc.destroy(--q);
posted @ 2020-10-29 20:17  kingchou  阅读(99)  评论(0)    收藏  举报