统一初始化方法
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; // 1234
return 0;
}
auto关键字
auto i = 100; // i 是 int
auto p = new A(); // p 是 A *
auto k = 34343LL; // k 是 longlong
map<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> >::iterator
class 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.5
auto 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 int
decltype(a->x) x3; // x3 is double
decltype((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,2
shared_ptr<A> sp3;
A *p = sp1.get(); // p 指向 A(2)
cout << "2) " << p->n << endl; // 输出 2
sp3 = sp1; // sp3也托管A(2)
cout << "3) " << (*sp3).n << endl; // 输出2
sp1.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; // 输出 3
shared_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,2
2) 2
3) 2
4) sp1 is null
5) 3
before end main
3 destructor
end main
2 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 = false
int i = nullptr; // error nullptr不能自动转换为整型
}
/******************* 输出
equal 1
equal 2
equal 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 constructor
String(String &&s) : str(s.str)
{
cout << "move constructor called\n";
s.str = new char[1];
s.str[0] = 0;
}
// move assignment
String &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 constructor
a = move(b); // move(b)为右值,因此这里会调用 move assignment
b = move(tmp); // move(tmp)为右值,因此这里会调用 move assignment
}
int main()
{
// String &r = String("this"); // error
String 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
******
this
move constructor called
move operator= called
move operator= called
hello
*****************/
可移动但不可复制的对象
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 error
func2(a1); // compile error
func();
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;
else
cout << "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.7
100
225
201,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; // 输出 10
for_each(a.begin(), a.end(), [](int x) { cout << x << " "; });
return 0;
}
/************** 输出
10
2 4 6 8
***************/