C++读书笔记(牛客网)
1.constexpr变量:声明为constexpr的变量一定是一个常量,新标准允许定义一种特殊的constexpr函数使得编译时就可计算结果,这样就能用constexpr函数去初始化constexpr变量。
2.类型别名:1.typedef 2.using SI = Sales_item; //SI是Sales_item的别名声明,把等号左侧的名字规定成等号右侧类型的别名 3.using可以起模板别名
3.auto:auto让编译器通过初始值来推算变量类型。auto i = 0, *p = &i; //ok auto sz = 0, pi = 3.14; //error, 类型不统一
auto一般会忽略顶层const,保留底层const。如果希望保留顶层const,要明确指出 const auto p = ci;
设置类型为auto的引用时,初始值中的顶层const属性保留。
底层 * 顶层: int const * const
4.decltype:类型指示符,顶层const能被保留,decltype((i)) d; //error, 对表达式套括号的结果永远是引用,不套括号则仅当i是引用时,才是引用。
5.范围for语句:for(declaration: expression) statement
expression是一个对象,表示一个序列;declaration部分定义一个变量,被用于访问序列中的基础元素,每次迭代该变量会被初始化为expression的下一个元素值。
如:
1 vector<int> v = {0, 1, 2, 3, 4, 5};
2 for(auto &r: v)
3 r *= 2;
6.标准库begin()和end():begin(arr)返回指向arr首元素的指针, end(arr)返回指向arr尾元素下一位置的指针。
7.列表初始化返回值:vector
8.定义尾置返回类型:任何函数的定义都能使用尾置返回类型,但对返回类型比较复杂的函数最有效,比如返回数组的指针或数组的引用。尾置返回类型跟在形参列表后,并以->开头,本应该出现返回类型的地方则放置auto。比如:
auto func(int i) -> int() [10];//返回类型为int()[10]
9.容器的列表初始化:vector
10.容器的emplace操作:emplace_frnont, emplace, emplace_back, 这些操作构造而不是拷贝元素,c.emplace(iter, "999-9999"); //向iter指向的位置插入以"999-9999"为构造参数的元素
11.lambda:
`**[**`capture `**]**` `**(**`params `**)**`mutableexceptionattribute `**->**`ret `**{**`body `**}**` | (1) |
`**[**`capture `**]**` `**(**`params `**)**` `**->**`ret `**{**`body `**}**` | (2) |
`**[**`capture `**]**` `**(**`params `**)**` `**{**`body `**}**` | (3) |
`**[**`capture `**]**` `**{**`body `**}**` | (4) |
mutable 修饰符说明 lambda 表达式体内的代码可以修改被捕获的变量,并且可以访问被捕获对象的 non-const 方法。
exception说明 lambda 表达式是否抛出异常(**noexcept**
),以及抛出何种异常,类似于void f()throw(X, Y)。
attribute用来声明属性。
[] // 不捕获任何外部变量
[=] // 以值的形式捕获所有外部变量
[&] // 以引用形式捕获所有外部变量
[x, &y] // x 以传值形式捕获,y 以引用形式捕获
[=, &z] // z 以引用形式捕获,其余变量以传值形式捕获
[&, x] // x 以值的形式捕获,其余变量以引用形式捕获
另有一点需注意。对于 [=] 或 [&] 的形式,lambda 表达式可直接使用 this 指针。但对于 [] 的形式,如果要使用 this 指针,必须显式传入:[this]() { this->someFunc(); }();
lambda后紧接();表示直接调用函数,括号内为参数。例:
http://wenku.baidu.com/view/77cd432e647d27284b73514b.html?from=search
std::vector<int> c { 1,2,3,4,5,6,7 };
int x = 5;
c.erase(std::remove_if(c.begin(), c.end(), [x](int n) { return n < x; } ), c.end());
for (auto i: c) {
std::cout << i << ' ';
}
std::cout << endl;
// the type of a closure cannot be named, but can be inferred with auto
auto func1 = [](int i) { return i+4; };
std::cout << "func1: " << func1(6) << 'n';
// like all callable objects, closures can be captured in std::function
// (this may incur unnecessary overhead)
std::function<int(int)> func2 = [](int i) { return i+4; };
std::cout << "func2: " << func2(6) << 'n';
string result = [](const string & str) { return "Hello from " + str; }("second Lambda");
cout << "Result: " << result << endl;
View Code
lambda的捕获列表只用于局部非static变量,lambda可以直接使用局部static变量和它所在函数之外声明的名字。值捕获的变量的值是在lambda创建时拷贝而不是在调用时拷贝,引用捕获则使用引用所绑定的对象,与正常引用类似,要保证lambda调用时变量是存在的。
每个lambda的类型都是唯一的,一般只能通过decltype和模板匹配来获得其类型。
vector<string> ve;
int sz = 10;
//接受一元谓词的算法
auto it = find_if(ve.begin(), ve.end(), [sz](const string &a){return a.size() >= sz; } );
//接受二元谓词的算法
sort(ve.begin(), ve.end(), [](const string &a, const string &b){ return a.size() < b.size();} );
12.标准库bind函数:
参数绑定http://blog.csdn.net/fjb2080/article/details/7527715
auto newCallable = bind(callable, arg_list);
arg_list中的参数可能包含形如_n的名字,其中n是整数,表示newCallable的参数,占据了传递给newCallable的参数的位置,_n表示为newCallable的第n个参数,在命名空间std::placeholeders里。
using namespace std::placeholders;
//例1:
bool check_size(const string &s, string::size_type sz){
return s.size() >= sz;
}
auto check6 = bind(check_size, _1, 6);
string s = "hello";
bool b1 = check6(s);//check6(s)会调用check_size(s, 6)
//例2:f是一个包含5个参数的函数
auto g = bind(f, a, b, _2, c, _1);
g(X, Y);//即f(a, b, Y, c, X);
//例3:ve是vector容器,cmp是一个比较函数
sort(ve.begin(), ve.end(), cmp);
sort(ve.begin(), ve.end(), bind(cmp, _2, _1));//按cmp逆序排列
13.智能指针
shared_ptr允许多个指针指向同一个对象, unique_ptr则独占所指向的对象。
智能指针是一种类模板。
默认初始化的智能指针中保存着空指针,内部有一个关联的计数器,计数器为0时释放自己管理的对象。
shared_ptr
附: shard_ptr与unique_ptr的简单实现
1 // https://www.cnblogs.com/howo/p/8468713.html
2
3 //
4 // SharedPtr.hpp
5 // SharedPtr
6 //
7 // Created by 顾浩 on 24/2/18.
8 // Copyright © 2018 顾浩. All rights reserved.
9 //
10
11 #ifndef SHARED_PTR_H
12 #define SHARED_PTR_H
13
14 #include <iostream>
15
16 using namespace std;
17
18 template<typename T>
19 class SharedPtr {
20 public:
21 SharedPtr() : _ptr((T *)0), _refCount(0)
22 {
23 }
24
25 SharedPtr(T *obj) : _ptr(obj), _refCount(new int(1))
26 {
27 cout<<"create object : "<<*_ptr<<"trefCount = 1"<<endl;
28 }
29
30 SharedPtr(SharedPtr &other) : _ptr(other._ptr), _refCount(&(++*other._refCount))
31 {
32 cout<<"copy constructor : "<<*_ptr<<"trefCount = "<<*_refCount<<endl;
33 }
34
35 ~SharedPtr()
36 {
37 if(_ptr && --*_refCount == 0) {
38 cout<<*_ptr<<"trefCount = 0. delete the _ptr:"<<*_ptr<<endl;
39 delete _ptr;
40 delete _refCount;
41 }
42 }
43
44 SharedPtr &operator=(SharedPtr &other)
45 {
46 if(this==&other) return *this;
47 ++*other._refCount;
48 if(--*_refCount == 0) {
49 cout<<"in function operator = . delete "<<*_ptr<<endl;
50 delete _ptr;
51 delete _refCount;
52 }
53 _ptr = other._ptr;
54 _refCount = other._refCount;
55 cout<<"in function operator = . "<<*_ptr<<"t_refCount = "<<*_refCount<<endl;
56 return *this;
57 }
58
59 T *operator->()
60 {
61 if(_refCount == 0) return 0;
62 return _ptr;
63 }
64
65 T &operator*()
66 {
67 if (_refCount == 0) return (T*)0;
68 return *_ptr;
69 }
70
71 private:
72 T *_ptr;
73 int *_refCount; //should be int*, rather than int
74 };
75
76 #endif /* SharedPtr_h */
View Code
1 #ifndef _UNIQUE_PTR_H
2 #define __UNIQUE_H
3 class Delete {
4 public:
5 template<typename T>
6 void operator()(T *p) const {
7 delete p;
8 }
9 };
10 template<typename T,typename D = Delete >
11 class unique_ptr {
12 public:
13 explicit unique_ptr(T *pp = nullptr ,const D &dd = D() ):
14 un_ptr(pp), del(dd)
15 {
16 }
17
18 ~unique_ptr()
19 {
20 del(un_ptr);
21 }
22
23 /* 不支持拷贝与赋值 */
24 unique_ptr(const unique_ptr&) = delete ;
25 unique_ptr& operator=(const unique_ptr& ) = delete ;
26
27 /* 移动赋值与移动拷贝 */
28 unique_ptr( unique_ptr&& right_value):
29 un_ptr(right_value.un_ptr),del(std::move(right_value.del)) {
30 right_value.un_ptr = nullptr ;
31 }
32
33 unique_ptr& operator=( unique_ptr&& right_value ) noexcept {
34 if(this != &right_value ){
35 std::cout << "operator && right_value " << std::endl ;
36 del(*this);
37 un_ptr = right_value.un_ptr;
38 del = std::move(right_value.del);
39 right_value.un_ptr = nullptr ;
40 }
41 return *this ;
42 }
43
44 //u.release() u 放弃对指针的控制权,返回指针,并将 u 置为空
45 T* release(){
46 T *tmp = un_ptr ;
47 un_ptr = nullptr ;
48 return tmp;
49 }
50
51 /*
52 u.reset() 释放u指向的对象
53 u.reset(q) 如果提供了内置指针q,就令u指向这个对象
54 u.reset(nullptr) 将 u 置为空
55 */
56 void reset(T* q = nullptr){
57 del(un_ptr);
58 un_ptr = q;
59 }
60 void swap(unique_ptr &other ) noexcept {
61 std::swap(un_ptr, other.un_ptr);
62 std::swap(del, other.del) ;
63 }
64 T* get() { return un_ptr; }
65 D& get_deleter(){ return del; }
66 T& operator*() { return *un_ptr; }
67 T* operator->() { return un_ptr; }
68 private:
69 T *un_ptr = nullptr ;
70 D del ;
71 };
72 #endif
View Code
原文链接: https://www.cnblogs.com/dirge/p/6204067.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/246397
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!