标签:
一.统一的初始化方法
1 int arr[3]{1, 2, 3}; 2 vector<int> iv{1, 2, 3}; 3 map<int, string> mp{{1, "a"}, {2, "b"}}; 4 string str{"Hello World"}; 5 int * p = new int[20]{1,2,3}; 6 struct A { 7 int i,j; A(int m,int n):i(m),j(n) { } 8 }; 9 A func(int m,int n ) { return {m,n}; } 10 int main() { A * pa = new A {3,7}; }
二.成员变量默认初始值
1 class B 2 { 3 public: 4 int m = 1234; 5 int n; 6 }; 7 int main() 8 { 9 B b; 10 cout << b.m << endl; //输出 1234 11 return 0; 12 }
三.auto关键字
用于定义变量,编译器可以自动判断变量的类型
1 auto i = 100; // i 是 int 2 auto p = new A(); // p 是 A * 3 auto k = 34343LL; // k 是 long long 4 map<string,int,greater<string> > mp; 5 for( auto i = mp.begin(); i != mp.end(); ++i) 6 cout << i->first << "," << i->second; 7 //i的类型是: map<string,int,greater<string> >::iterator 8 9 class A { }; 10 A operator + ( int n,const A & a) 11 { 12 return a; 13 } 14 template <class T1, class T2> 15 auto add(T1 x, T2 y) -> decltype(x + y) { 16 return x+y; 17 } 18 auto d = add(100,1.5); // d是double d=101.5 19 auto k = add(100,A()); // d是A类型
四.decltype 关键字
求表达式的类型
1 int i; 2 double t; 3 struct A { double x; }; 4 const A* a = new A(); 5 decltype(a) x1; // x1 is A * 6 decltype(i) x2; // x2 is int 7 decltype(a->x) x3; // x3 is double 8 decltype((a->x)) x4 = t; // x4 is double&
五.智能指针shared_ptr
? 头文件: <memory>
? 通过shared_ptr的构造函数,可以让shared_ptr对象托管一个new运算符返回的指针,写法如下:回的指针,写法如下:回的指针,写法如下:
shared_ptr<T> ptr(new T); // T 可以是 int ,char, 类名等各种类型
此后ptr就可以像 T* 类型的指针一样来使用,即 *ptr 就是用new动态分配的
那个对象,而且不必操心释放内存的事。
? 多个shared_ptr对象可以同时托管一个指针,系统会维护一个托管计数。当
无shared_ptr托管该指针时, delete该指针。
? shared_ptr对象不能托管指向动态分配的数组的指针,否则程序运行会出错
1 #include <memory> 2 #include <iostream> 3 using namespace std; 4 struct A { 5 int n; 6 A(int v = 0):n(v){ } 7 ~A() { cout << n << " destructor" << endl; } 8 }; 9 int main() 10 { 11 shared_ptr<A> sp1(new A(2)); //sp1托管A(2) 12 shared_ptr<A> sp2(sp1); //sp2也托管 A(2) 13 cout << "1)" << sp1->n << "," << sp2->n << endl; //输出1)2,2 14 shared_ptr<A> sp3; 15 A * p = sp1.get(); //p 指向 A(2) 16 cout << "2)" << p->n << endl; 17 //输出结果: 18 // 1)2,2 19 // 2)2 20 sp3 = sp1; //sp3也托管 A(2) 21 cout << "3)" << (*sp3).n << endl; //输出 2 22 sp1.reset(); //sp1放弃托管 A(2) 23 if( !sp1 ) 24 cout << "4)sp1 is null" << endl; //会输出 25 A * q = new A(3); 26 sp1.reset(q); // sp1托管q 27 cout << "5)" << sp1->n << endl; //输出 3 28 shared_ptr<A> sp4(sp1); //sp4托管A(3) 29 shared_ptr<A> sp5; 30 //sp5.reset(q); 不妥,会导致程序出错 31 sp1.reset(); //sp1放弃托管 A(3) 32 cout << "before end main" <<endl; 33 sp4.reset(); //sp1放弃托管 A(3) 34 cout << "end main" << endl; 35 return 0; //程序结束,会delete 掉A(2) 36 } 37 //输出结果: 38 //1)2,2 39 //2)2 40 //3)2 41 //4)sp1 is null 42 //5)3 43 //before end main 44 //3 destructor 45 //end main 46 //2 destructor
1 #include <iostream> 2 #include <memory> 3 using namespace std; 4 struct A { 5 ~A() { cout << "~A" << endl; } 6 }; 7 int main() 8 { 9 A * p = new A; 10 shared_ptr<A> ptr(p); 11 shared_ptr<A> ptr2; 12 ptr2.reset(p); //并不增加ptr中对p的托管计数 13 cout << "end" << endl; 14 return 0; 15 } 16 //输出结果: 17 //end 18 //~A 19 //~A 20 //之后程序崩溃, 21 //因p被delete两次
六.空指针nullptr
1 #include <memory> 2 #include <iostream> 3 using namespace std; 4 int main() { 5 int* p1 = NULL; 6 int* p2 = nullptr; 7 shared_ptr<double> p3 = nullptr; 8 if(p1 == p2) 9 cout << "equal 1" <<endl; 10 if( p3 == nullptr) 11 cout << "equal 2" <<endl; 12 if( p3 == p2) ; // error 13 if( p3 == NULL) 14 cout << "equal 4" <<endl; 15 bool b = nullptr; // b = false 16 int i = nullptr; //error,nullptr不能自动转换成整型 17 return 0; 18 } 19 //去掉出错的语句后输出: 20 //equal 1 21 //equal 2 22 //equal 4
七.基于范围的for循环
1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 struct A { int n; A(int i):n(i) { } }; 5 int main() { 6 int ary[] = {1,2,3,4,5}; 7 for(int & e: ary) 8 e*= 10; 9 for(int e : ary) 10 cout << e << ","; 11 cout << endl; 12 vector<A> st(ary,ary+5); 13 for( auto & it: st) 14 it.n *= 10; 15 for( A it: st) 16 cout << it.n << ","; 17 return 0; 18 } 19 //输出: 20 //10,20,30,40,50, 21 //100,200,300,400,500,
八.右值引用和move语义
右值:一般来说,不能取地址的表达式,就是右值,能取地址的,就是左值
class A { };
A & r = A(); // error , A()是无名变量,是右值
A && r = A(); //ok, r 是右值引用
主要目的是提高程序运行的效率,减少需要进行深拷贝的对象进行深拷贝的次数。的次数。
1 #include <iostream> 2 #include <string> 3 #include <cstring> 4 using namespace std; 5 class String 6 { 7 public: 8 char * str; 9 String():str(new char[1]) { str[0] = 0;} 10 String(const char * s) { 11 str = new char[strlen(s)+1]; 12 strcpy(str,s); 13 } 14 String(const String & s) { 15 cout << "copy constructor called" << endl; 16 str = new char[strlen(s.str)+1]; 17 strcpy(str,s.str); 18 } 19 20 String & operator=(const String & s) { 21 cout << "copy operator= called" << endl; 22 if( str != s.str) { 23 delete [] str; 24 str = new char[strlen(s.str)+1]; 25 strcpy(str,s.str); 26 } 27 return * this; 28 } 29 // move constructor 30 String(String && s):str(s.str) { 31 cout << "move constructor called"<<endl; 32 s.str = new char[1]; 33 s.str[0] = 0; 34 } 35 36 // move assigment 37 String & operator = (String &&s) { 38 cout << "move operator= called"<<endl; 39 if (str!= s.str) { 40 str = s.str; 41 s.str = new char[1]; 42 s.str[0] = 0; 43 } 44 return *this; 45 } 46 ~String() { delete [] str; } 47 }; 48 template <class T> 49 void MoveSwap(T& a, T& b) { 50 T tmp(move(a)); // std::move(a)为右值,这里会调用move constructor 51 a = move(b); // move(b)为右值,因此这里会调用move assigment 52 b = move(tmp); // move(tmp)为右值,因此这里会调用move assigment 53 } 54 55 int main() 56 { 57 //String & r = String("this"); // error 58 String s; 59 s = String("this"); 60 cout << "****" << endl; 61 cout << s.str << endl; 62 String s1 = "hello",s2 = "world"; 63 MoveSwap(s1,s2); 64 cout << s2.str << endl; 65 return 0; 66 } 67 //输出: 68 //move operator= called 69 //**** 70 //this 71 //move constructor called 72 //move operator= called 73 //move operator= called 74 //hello
九.无序容器(哈希表)
1 #include <iostream> 2 #include <string> 3 #include <unordered_map> 4 using namespace std; 5 int main() 6 { 7 unordered_map<string,int> turingWinner; //图灵奖获奖名单 8 turingWinner.insert(make_pair("Dijkstra",1972)); 9 turingWinner.insert(make_pair("Scott",1976)); 10 turingWinner.insert(make_pair("Wilkes",1967)); 11 turingWinner.insert(make_pair("Hamming",1968)); 12 turingWinner["Ritchie"] = 1983; 13 string name; 14 cin >> name; //输入姓名 15 4 16 unordered_map<string,int>::iterator p = turingWinner.find(name); 17 //据姓名查获奖时间 18 if( p != turingWinner.end()) 19 cout << p->second; 20 else 21 cout << "Not Found" << endl; 22 return 0; 23 } 24 //哈希表插入和查询的时间复杂度几乎是常数
十.正则表达式
1 #include <iostream> 2 #include <regex> //使用正则表达式须包含此文件 3 using namespace std; 4 int main() 5 { 6 regex reg("b.?p.*k"); 7 cout << regex_match("bopggk",reg) <<endl; //输出 1, 表示匹配成功 8 cout << regex_match("boopgggk",reg) <<endl; //输出 0, 表示匹配失败 9 cout << regex_match("b pk",reg) <<endl; //输出 1, 表示匹配成功 10 regex reg2("\\d{3}([a-zA-Z]+).(\\d{2}|N/A)\\s\\1"); 11 string correct="123Hello N/A Hello"; 12 string incorrect="123Hello 12 hello"; 13 cout << regex_match(correct,reg2) <<endl; //输出 1, 表示匹配成功 14 cout << regex_match(incorrect,reg2) << endl; //输出 0, 表示匹配失败 15 }
十一.Lambda表达式只使用一次的函数对象,能否不要专门为其编写一个类?
只调用一次的简单函数,能否在调用时才写出其函数体?
形式:
[外部变量访问方式说明符](参数表) ->返回值类型
{
语句组
}[=] 以传值的形式使用所有外部变量
[] 不使用任何外部变量
[&] 以引用形式使用所有外部变量
[x, &y] x 以传值形式使用, y 以引用形式使用
[=,&x,&y] x,y 以引用形式使用,其余变量以传值形式使用
[&,x,y] x,y 以传值的形式使用,其余变量以引用形式使用
“ ->返回值类型”也可以没有, 没有则编译器自动判断返回值类型。
1 int main() 2 { 3 int x = 100,y=200,z=300; 4 cout << [ ](double a,double b) { return a + b; } (1.2,2.5) << endl; 5 auto ff = [=,&y,&z](int n) { 6 cout <<x << endl; 7 y++; z++; 8 return n*n; 9 }; 10 cout << ff(15) << endl; 11 cout << y << "," << z << endl; 12 } 13 //输出: 14 //3.7 15 //100 16 //225 17 //201,301
1 int a[4] = { 4,2,11,33}; 2 sort(a,a+4,[ ](int x,int y)->bool { return x%10 < y%10; }); 3 for_each(a,a+4,[ ](int x) {cout << x << " " ;} ) ;
//11 2 33 4
1 #include <iostream> 2 #include <algorithm> 3 #include <vector> 4 using namespace std; 5 int main() 6 { 7 vector<int> a { 1,2,3,4}; 8 int total = 0; 9 for_each(a.begin(),a.end(),[&](int & x) {total += x; x*=2;}); 10 cout << total << endl; //输出 10 11 for_each(a.begin(),a.end(),[ ](int x) { cout << x << " ";}); 12 return 0; 13 } 14 //程序输出结果: 15 //10 16 //2 4 6 8
实现递归求斐波那契数列第n项:
function<int(int)> fib = [&fib](int n)
{ return n <= 2 ? 1 : fib(n-1) + fib(n-2);};
cout << fib(5) << endl; //输出5
function<int(int)> 表示返回值为 int, 有一个int参数的函数
#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" << endl;
str = new char[strlen(s.str)+1];
strcpy(str,s.str);
}
String & operator=(const String & s) {
cout << "copy operator= called" << endl;
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"<<endl;
s.str = new char[1];
s.str[0] = 0;
}
// move assigment
String & operator = (String &&s) {
cout << "move operator= called"<<endl;
if (str!= s.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 assigment
b = move(tmp); // move(tmp)为右值,因此这里会调用move assigment
}
int main()
{
//String & r = String("this"); // error
String s;
s = String("this");
cout << "****" << endl;
cout << s.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
标签:
原文地址:http://www.cnblogs.com/wanderingzj/p/5345940.html