c++11 新特性笔记

1.explicit
explicit 用来修饰类的构造函数,如果在类的构造函数前面加了explicit关键字,则在定义类的对象时,不能隐式转换

#include <iostream>
#include <string>
class CInt
{
	explicit CInt(int i){}
};
class CStr
{
	CStr(std::string str){}
};
 CInt ma(1);		//ok
 CInt mb = 2;		//false
 CStr mc = "mc";	//ok

2.仿函数

仿函数又称为函数对象,是一个能行使函数功能的类。仿函数的语法几乎和我们普通的函数调用一样,不过作为仿函数的类,必须重载operator()运算符,好处是方便传参。可以作为算法的方法,也可以作为std::thread的函数

struct func {
	 func(int i) :m_i(i) { std::cout << "构造函数" << std::endl; }
	 bool operator()(int a) 
	 {
		 return a > m_i;
	 }
	 int m_i;
 };
 std::vector<int> vec;
 vec.push_back(2);
 vec.push_back(8);
 std::cout << std::count_if(vec.begin(), vec.end(), func(7)) <<  std::endl;

3.thread
使用时注意的点

  1. 调用join等待线程结束的函数时,应该考虑异常的情况,跳过join函数,这样导致该线程无法正常的结束
struct func;
int mi = 0;
func f(mi);
std::thread t(f);
try{
	...
}
catch(...){
	t.join();	//出现异常时等待结束
	throw;
}
t.join();		//正常情况下结束
解决方法一
class thread_guard
{
public:
explicit thread_guard(std::thread& t):m_t(t){}
~thread_guard()
{
	if(t.joinable()){
		t.join();
	}
}
thread_guard(thread_guard& that) = delete;
thread_guard& operator=(thread_guard& that) = delete;
std::thread m_t;
}
std::thread t(f);
thread_guard g(t);
  1. 类的成员函数作为线程函数
class X
{
public:
	void do_something(int);
};
X my_x;
int num = 0;
std::thread t(&X::do_something,&my_x,num);
传入的第三个参数为成员函数的参数,提供的参数可以“移动”,但不能“拷贝”。
移动:原始对象中的数据转移给另一对象,而转移的这些数据就不再在原始对象中保存了。
  1. 如果不在构造完std::thread后调用join函数,可能会出错,因为有可能主线程已经结束了,子线程还没结束,导致回收资源时出错
  2. std::thread::hardware_concurrency返回能同时并发在一个程序中的线程数量。

4.lambda函数
意义:
参考某位博主的观点:使用lambda函数,在一些场景下就不必再单独定义一个常规函数,或是一个callable function object(仿函数)
函数的格式:
在这里插入图片描述
lambda表达式个人理解,主要用途
1. 用在算法中,如果代码简短,可替代函数指针,例

vector<int> vec;
for(int i = 0;i < 10;;){
	vec.push_back(i);
}
for_each(vec.begin(), vec.end(), [](int &n) {if (n % 2) n = -n; });
3. fdjlak

5.function
function是对象,但是是函数指针的作用

  1. 可以接lambda表达式
std::function<void<int>> f = [](int& n){if(n < 0) n = -n;};
  1. 可以和bind联合使用
  2. 待续

6.mutable

  1. 阻止const对变量修改的限制,一般用在用来修饰成员变量
class C
{
public:
	void ModifyData() const
	{
		i_num = 2;	//err
		m_str = "world"; //ok
	}
private:
	int i_num = 1;
	mutable std::string m_str = "hello";
};
  1. 用在lambda函数中

此处对const的用法说明一下

  1. 修饰形参
void func(const int i);
  1. 修饰返回值
const int func();
  1. 修饰成员函数

7.std::ref
c++本身有引用(&),考虑函数式编程在使用时,是对参数直接拷贝,而不是引用,为了使用引用。如果是值传递,则fun修改的是变量的副本。

void fun(int& i){}
void opps()
{
	int i = 0;
	std::thread t(fun,std::ref(i));//如果不是std::ref(i),传入i,则会报错
}

8.智能指针
在c++11中,智能指针有三个unique_ptr,shared_ptr,weak_ptr

  1. unique_ptr:同一时刻只能有一个unique_ptr指向给定对象,在多个unique_ptr之间可以使用std::move()进行转移。通过reset方法重新指定,通过release方法释放所有权,通过移动语义转移所有权,没有拷贝语义(使用delete删除了)。
std::unique_ptr<int> uptr(new int(10));  //绑定动态对象
std::unique_ptr<int> uptr2 = std::move(uptr); //轉換所有權
uptr2.release(); //释放所有权
  1. shared_ptr:多个指针指向相同的对象。shared_ptr使用计数,使用(拷贝和赋值)一次计数加1,每析构一次,内部计数减1。get函数获取原始指针。
int b = 20;
int *pb = &a;
std::shared_ptr<int> ptrb = std::make_shared<int>(b);
pb = ptrb.get(); //获取原始指针
  1. weak_ptr:对shared_ptr对指针的资源观测。
std::shared_ptr<int> sh_ptr = std::make_shared<int>(10);
std::weak_ptr<int> wp(sh_ptr);
if(!wp.expired()){
     std::shared_ptr<int> sh_ptr2 = wp.lock(); //get another shared_ptr
     *sh_ptr = 100;
     std::cout << wp.use_count() << std::endl;
}

9.std :: accumulate
累计范围内的值.返回将范围中的所有值累加[first,last)到init的结果.

accumulate (InputIterator first, InputIterator last, T init, BinaryOperation binary_op);

std::distance()
返回两个迭代器之间的距离
10.锁
锁有互斥锁(std::mutex)和自旋锁(std::spin_lock)
互斥锁使用场景为操作复杂,时间长,多线程会进行切换
自旋锁使用场景为操作简单,时间短,多线程不会切换
原子操作
将多条指令变成一条不可分割的指令

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MSDN_lsx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值