ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

现代C++实战(4)

2022-08-10 20:00:28  阅读:155  来源: 互联网

标签:实战 Singleton return int C++ 现代 inst mutex ptr


函数对象

c++98中的函数对象:重载()运算符

struct Add {
	Add(int n): n_(n){}
    int operator()(x) const {
        return x + n_;
    }
private:
    int n_;
}

Lambda表达式

auto add_2 = [](int x) {return x + 2;};

变量捕获

  • 本地变量按值捕获
  • & 按引用捕获

泛型Lambda

// 普通泛型函数
template<typename T1, typename T2>
auto sum(T1 x, T2 y) {
    return x + y;
}

// 等价的lambda表达式
auto sum = [](auto x, auto y) {
    return x + y;
};

bind和functional

plus<>()接受两个参数,bind将2绑定到第二个参数,如果不绑定,则用_1,_2用作占位符

transform(v.begin(), v.end(), v.begin(), bind(plus<>(), _1, 2))

function模板是一个包装

function<int(int, int)> a;	// 一个返回值为int,接受两个int参数的function对象

上述function对象,可以接受函数签名为int(int,int)的可调用的对象(lambda表达式,函数指针,函数对象,函数名)

函数式编程

要说清楚什么是函数式编程还是很困难的,不过大概的意思就是,把函数当参数传给其他的函数去执行。

可变模板和tuple

模板参数的个数是不定的,下面是个一般用法

template<typename T, typename ...Args>
inline unique_ptr<T>
make_unique (Args&&... args)
{
	return unique_ptr<T>(new T(forward<Args>(args)...));
}

这里用forward是为了保持原有的左右值特性(因为右值引用经过一次传参后会变成左值)

递归用法

求n个数的和,变参

template<typename T>
constexpr auto sum(T x) {
    return x;
}

template<typename T1, typename T2, typename... Args>
constexpr auto sum(T1, x, T2, y, Args... args) {
    return sum(x + y, args);
}

tuple

thread和future

基于thread的多线程

#include <thread>
#include <iostream>
using namespace std;

void func1() {
    this_thread::sleep_for(100ms);	// 全局函数
	cout << "func1!" << endl;
}

void func2() {
	cout << "func2!" << endl;
}

int main() {
	thread t1{ func1 };
	thread t2{ func2 };

	t1.join();	// 必须join或者detach
	t2.join();
}

mutex 互斥量

  • mutex
  • recursive_mutex
  • timed_mutex
  • recursive_timed_mutex
  • shared_mutex
  • shared_timed_mutex

lock_gard,mutex的RAII包装类

  • unique_lock
  • scope_lock

future

#include <thread>
#include <iostream>
#include <future>
using namespace std;

int func1() {
	this_thread::sleep_for(100ms);
	cout << "func1!" << endl;
	return 1;
}

void func2() {
	cout << "func2!" << endl;
}

int main() {
	auto a = async(launch::async, func1);
	this_thread::sleep_for(1s);
	cout << "I am waiting now\n";
	cout << "Answer: " << a.get() << endl;
}
  • async指定执行的方式,launch::async表示异步
  • 返回一个future对象,用该对象获取结果

内存模型和atomic

双重检查

看一个单例模式

class Singleton{
public:
    static Singleton* instance();
private:
    static Singleton* inst_ptr_;
}

如何保证多线程下,inst_ptr_不会被初始化两次?

// 一阶段
// 每次调用都需要加锁
Singleton* Singleton::instance() {
    {
        lock_guard lock;
        if (inst_ptr == nullptr) {
        inst_ptr_ = new Singleton();
    }
    return inst_ptr_;
}

// 二阶段
// 初始化以后就不用枷锁了
Singleton* Singleton::instance() {
    if (inst_ptr_ == nullptr) {
        lock_guard lock;
        if (inst_ptr == nullptr) {
            inst_ptr_ = new Singleton();
        }
    }
    return inst_ptr_;
}

volatile

防止编译器“优化”掉对内存的读写

atomic

c++11 对原子对象进行了封装

原子操作:读,写,读-修改-写(读到内存,修改,写回内存)

标签:实战,Singleton,return,int,C++,现代,inst,mutex,ptr
来源: https://www.cnblogs.com/destinyzk/p/16573716.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有