统一初始化方法
int arr[3]{1,2,3};vector<int> iv{1, 2, 3};map<int, string> mp{{1, "a"}, {2, "b"}};string str{"Hello World"};int * p = new int[20]{1,2,3};struct A {int i, j; A(int m, int n):i(m), j(n){ }};A func(int m, int n) { return {m, n}; }int main() {A * pa = new A {3, 7};return 0;}
成员变量默认初始值
class B {public:int m = 1234;int n;};int main() {B b;cout << b.m << endl; // 1234return 0;}
auto关键字
auto i = 100; // i 是 intauto p = new A(); // p 是 A *auto k = 34343LL; // k 是 longlongmap<string,int,greater<string> > mp;for(auto i = mp.begin(); i != mp.end(); ++i)cout << i->first << "," << i->second;// i的类型是: map<string, int, greater<string> >::iteratorclass A {};A operator + (int n, const A & a) {return a;}template <class T1, class T2>auto add(T1 x, T2 y) -> decltype(x+y) {return x + y;}auto d = add(100, 1.5); // d 是 double d = 101.5auto k = add(100, A()); // k是A类型
decl关键字
求表达式的类型
int i;double t;struct A {double x;};const A * a = new A();decltype(a) x1; // x1 is A *decltype(i) x2; // x2 is intdecltype(a->x) x3; // x3 is doubledecltype((a->x)) x4 // x4 is double &
智能指针shared_ptr

#include <memory>#include <iostream>using namespace std;struct A{int n;A(int v = 0) : n(v) {}~A() { cout << n << " destructor" << endl; }};int main(){shared_ptr<A> sp1(new A(2)); // sp1托管A(2)shared_ptr<A> sp2(sp1); // sp2也托管A(2)cout << "1) " << sp1->n << "," << sp2->n << endl;// 输出 1) 2,2shared_ptr<A> sp3;A *p = sp1.get(); // p 指向 A(2)cout << "2) " << p->n << endl; // 输出 2sp3 = sp1; // sp3也托管A(2)cout << "3) " << (*sp3).n << endl; // 输出2sp1.reset(); // sp1放弃托管A(2)if (!sp1) // 如果sp1没有托管任何指针cout << "4) sp1 is null" << endl; // 输出A *q = new A(3);sp1.reset(q); // sp1托管A(3)cout << "5) " << sp1->n << endl; // 输出 3shared_ptr<A> sp4(sp1); // sp4托管A(3)shared_ptr<A> sp5;// sp5.reset(q); 不妥,会导致程序出错sp1.reset(); // sp1放弃托管A(3)cout << "before end main" << endl;sp4.reset();cout << "end main" << endl;return 0; // 程序结束,会delete A(2)}/******************** 输出1) 2,22) 23) 24) sp1 is null5) 3before end main3 destructorend main2 destructor***********************/
使用注意事项
#include <iostream>#include <memory>using namespace std;struct A{~A( cout << "~A" << endl;)};int main() {A * p = new A();shared_ptr<A> ptr(p);shared_ptr<A> ptr2;ptr2.reset(p); // 并不增加ptr中对p的托管计数cout << "end" << endl;return 0;}/***************** 输出end~A~A之后程序崩溃,因p被delete两次******************/
nullptr
#include <memory>#include <iostream>using namespace std;int main() {int * p1 = NULL;int * p2 = nullptr;shared_ptr<double> p3 = nullptr;if(p1 == p2)cout << "equal 1" << endl;if(p3 == nullptr)cout << "equal 2" << endl;if(p3 == p2); // error 对象类型不同if(p3 == NULL)cout << "equal 4\n";bool b = nullptr; // b = falseint i = nullptr; // error nullptr不能自动转换为整型}/******************* 输出equal 1equal 2equal 4********************/
基于范围的for循环
注意 for 中参数类型是否写引用
#include <iostream>#include <vector>using namespace std;struct A{int n;A(int i) : n(i) {}};int main(){int ary[]{1, 2, 3, 4, 5};for (int &e : ary)e *= 10;for (int e : ary)cout << e << ",";cout << endl;vector<A> st(ary, ary + 5);for (auto &it : st)it.n *= 10;for (A it : st)cout << it.n << ",";cout << endl;return 0;}/******************** 输出10,20,30,40,50,100,200,300,400,500,*********************/
右值引用和move语义

#include <iostream>#include <string>#include <cstring>using namespace std;class String{public:char *str;String() : str(new char[1]) { str[0] = 0; }String(const char *s){str = new char[strlen(s) + 1];strcpy(str, s);}String(const String &s){cout << "copy constructor called\n";str = new char[strlen(s.str) + 1];strcpy(str, s.str);}String &operator=(const String &s){cout << "copy operator= called\n";if (str != s.str){delete[] str;str = new char[strlen(s.str) + 1];strcpy(str, s.str);}return *this;}// move constructorString(String &&s) : str(s.str){cout << "move constructor called\n";s.str = new char[1];s.str[0] = 0;}// move assignmentString &operator=(String &&s){cout << "move operator= called\n";if (str != s.str){delete[] str;str = s.str;s.str = new char[1];s.str[0] = 0;}return *this;}~String() { delete[] str; }};template <class T>void MoveSwap(T &a, T &b) // 有意的避免深拷贝{T tmp(move(a)); // std::move(a)为右值,这里会调用 move constructora = move(b); // move(b)为右值,因此这里会调用 move assignmentb = move(tmp); // move(tmp)为右值,因此这里会调用 move assignment}int main(){// String &r = String("this"); // errorString s;s = String("ok"); // String("ok")是右值cout << "******" << endl;String &&r = String("this");cout << r.str << endl;String s1 = "hello", s2 = "world";MoveSwap(s1, s2);cout << s2.str << endl;return 0;}/**************** 输出move operator= called******thismove constructor calledmove operator= calledmove operator= calledhello*****************/

可移动但不可复制的对象
struct A {A(const A & a) = delete;A(const A && a) {cout << "move" << endl;}A() {};};A b;A func() {A a;return a;}void func2(A a) {}int main() {A a1;A a2(a1); // compile errorfunc2(a1); // compile errorfunc();return 0;}
无序容器(哈希表)
跟 map 的完全一样,只是底层使用的哈希表实现
#include <iostream>#include <unordered_map>#include <string>using namespace std;int main(){unordered_map<string, int> turingWinner; // 图灵奖获奖名单turingWinner.insert(make_pair("Dijkstra", 1972));turingWinner.insert(make_pair("Scott", 1976));turingWinner.insert(make_pair("Wilkes", 1967));turingWinner.insert(make_pair("Hamming", 1968));turingWinner["Ritchie"] = 1983;string name;cin >> name;unordered_map<string, int>::iterator p = turingWinner.find(name);if (p != turingWinner.end())cout << p->second;elsecout << "Not found.\n";return 0;}
正则表达式
#include <iostream>#include <regex>using namespace std;int main(){regex reg("b.?p.*k");cout << regex_match("bopggk", reg) << endl; // 输出1,表示匹配成功cout << regex_match("boopgggk", reg) << endl; // 输出0,表示匹配失败cout << regex_match("b pk", reg) << endl; // 输出1,表示匹配成功regex reg2("\\d{3}([a-zA-z]+).(\\d{2}|N/A)\\s\\1");string correct = "123Hello N/A Hello";string incorrect = "123Hello 12 hello";cout << regex_match(correct, reg2); // 输出1,匹配成功cout << regex_match(incorrect, reg2); // 输出0 匹配失败return 0;}
lambda表达式

#include <iostream>using namespace std;int main(){int x = 100, y = 200, z = 300;cout << [](double a, double b) { return a + b; }(1.2, 2.5) << endl;auto ff = [=, &y, &z](int n) {cout << x << endl;y++;z++;return n * n;};cout << ff(15) << endl;cout << y << "," << z << endl;return 0;}/****************** 输出3.7100225201,301*******************/
#include <iostream>#include <algorithm>using namespace std;int main(){int a[4] = {4, 2, 11, 33};sort(a, a + 4, [](int x, int y) -> bool { return x % 10 < y % 10; });for_each(a, a + 4, [](int x) { cout << x << " "; });return 0;}/************ 输出11 2 33 4*************/
#include <iostream>#include <algorithm>#include <vector>using namespace std;int main(){vector<int> a{1, 2, 3, 4};int total = 0;for_each(a.begin(), a.end(), [&](int &x) { total += x; x *= 2; });cout << total << endl; // 输出 10for_each(a.begin(), a.end(), [](int x) { cout << x << " "; });return 0;}/************** 输出102 4 6 8***************/

