c++11学习笔记

收集

1,线程同步

2,函数

3,模板

4,lambda

5,方法

6,类与类方法

7,关键字

写笔记的目的是,可以方便自己很久来学的时候可以快速查阅

基本互斥锁

std::mutex mtx;



互斥锁的一般用法


在函数体内锁,函数体外自动解锁

std::lock_guard<std::mutex> guard(mtx);


可以自定义锁的范围

std::unique_lock<std::mutex> lck1, lck2;

lck1 = std::unique_lock<std::mutex>(bar, std::defer_lock);

lck2 = std::unique_lock<std::mutex>(foo, std::defer_lock);

std::lock(lck1, lck2);

条件变量std::condition_variable

使用条件变量的场景

1,先获得锁(用于保证资源的共享访问)

2,wait语句释放锁,阻塞,等待其他线程notify唤醒,唤醒后,先获取锁,得到锁后,

判断条件是否返回true

如果为true,程序往下执行了,此时锁还在。

如果为false,释放锁,休眠,等待下一次notify唤醒

template<typename T>

class threadsafe_queue

{

private:

mutable std::mutex mut; // 1 互斥量必须是可变的

std::queue<T> data_queue;

std::condition_variable data_cond;

public:

void push(T new_value)

{

    std::lock_guard<std::mutex> lk(mut);

    data_queue.push(new_value);

    data_cond.notify_one(); //生产者线程insert数据后,notify通知消费者

}

void wait_and_pop(T& value)

{

    std::unique_lock<std::mutex> lk(mut);

    //消费者线程收到通知,检查wait条件变量,队列不为空退出等待,取队列数据处理

    data_cond.wait(lk,[this]{return !data_queue.empty();});

    value=data_queue.front();

    data_queue.pop();

}

};

function

参考:C++11新特性总结_小杰312的博客-CSDN博客

//函数指针
int add1(int a, int b) {
	return a + b;
}
 
//仿函数
struct Add {
	int operator()(int a, int b) {
		return a + b;
	}
	int a, b;
};
int main() {
	auto add2 = [](int a, int b){ return a + b; };	//当然可以在()->指定后置返回类型
	//auto add2 = [](int a, int b)->int { return a + b; };	
	function<int(int, int) > func1 = add1;		//函数名
	function<int(int, int) > func2 = Add();		//函数对象
	function<int(int, int) > func3 = add2;		//lambda表达式
	std::cout << func1(3, 5) << std::endl;
	std::cout << func2(3, 5) << std::endl;
	std::cout << func3(3, 5) << std::endl;
	while (1);
	return 0;
}

std:bind

std::bind的头文件是 <functional>,它是一个函数适配器,接受一个可调用对象(callable object),生成一个新的可调用对象来“适应”原对象的参数列表。

C++11中的std::bind 简单易懂_云飞扬_Dylan的博客-CSDN博客

可调用对象

C++11:可调用对象_@一鸣惊人的博客-CSDN博客

lock_guard

std::lock_guard的原理和应用_水墨长天的博客-CSDN博客

构造时,将传入的互斥量加锁,析构时,将传入的互斥量解锁,简单方便

拷贝构造函数

从零开始的移动构造函数,拷贝构造函数详解(C++)_移动拷贝构造_白铭单的博客-CSDN博客

explicit关键字

C++11 explicit关键字的详细讲解_随你而归的云彩的博客-CSDN博客

显示构造,在写代码阶段就能检测出来。也就是加上之后,写代码时会报错。

Son s1(18); //显示构造

Son s2 = 20; //隐式构造

完美转发

解决模板函数传参时,能够方便地根据传入参数(左值或者右值)实现完美传给模板函数内的函数

C++11完美转发及实现方法详解

C/C++编译原理

预处理 -E

作用:处理宏定义和include,去除注释,不会对语法进行检查,生成.i文件

命令:
gcc -E test.c -o test.i

编译 -S

作用:检查语法,生成汇编指令, .s文件。

命令:
gcc -s test.c -o test.s

汇编 -C

作用: 翻译成符合一定格式的机器代码, 生成.o文件。
命令
gcc -c test.c -o test.o

模板编程

1.3 模板-函数模板特化_哔哩哔哩_bilibili

模板简单示例

#include<iostream>
using namespace std;

template <typename T>
T add(T a, T b)
{
    return a+b;
}

// 特化(全特化)
template <>
const char* add<const char*>(const char * str1, const char* str2)
{
    std::stringstream ss;
    ss << str1 <<str2;
    std::string ret = ss.str();
    return ret.c_str();
}


int main()
{
    auto k1 = add(1231,2312);
    auto k2 = add(0.23f, 123.2f);
    auto k3 = add("dsf", "fdsf");
    cout<<k3<<endl;

    return 0;
}

/*
    T可以任意写
    编译器自动推导类型
    汇编后的本质其实是编译器自动生成两个函数
    如果类型无法推导出来,不会报错,会按函数的地址进行计算比较

    
*/

默认模板参数&非类型模板参数

#include<iostream>
#include<sstream>

using namespace std;


// 多个模板参数 &  非类型模板参数
// 可以用来根据输入参数的大小,实现自动分配内存
// 函数模板的本质其实是编译器推导,帮助我们写出每个不同参数的实例

// typename 可以写成class,但是一般都用typename,容易和类class定义混淆
template <typename T1, typename T2,  int N>
T1* CC_ALLOC()
{
    try
    {
        T2 a;
        T1* p = new T1(N);
        for(size_t i=0;i<N;i++){
            p[i] = 1;
        }
        return p;
    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << '\n';
        return nullptr;
    }
    
}


int main()
{
    // 用封装的模板实现用new分配堆空间
    auto* p = CC_ALLOC<int, int, 5>();
    cout<<*p<<endl;
   
    return 0;
}


// 如果有实例化的函数,和模板函数重复,会优先调用现用,不用去解析不存在的

int Max(int a, int b){
    return a>b?a:b;
}

template<typename T>
T Max(T a, T b)
{
    return a>b?a:b;
}

模板参数限定

template <typename T>
T add(T a, T b)
{
    // 模板参数限定,编译的时候,如果T 不是int 也不是float,直接编译报错
    static_assert(std::is_integral<T>::value || std::is_floating_point<T>::value, "Error Type CC")
    return a+b;
}

非基础类型用重载操作符实现复杂业务

#include<iostream>

class Person{
private:
    int _age;
public:
    Person(int age): _age(age){};

    // 重载>操作符
    bool operator>(const Person& ref){
        return this->_age > ref._age;
    }
};

template<typename T>
T Max(T a, T b)
{
    return a>b?a:b;
}


int main()
{
    Person P1(18);
    Person P2(20);
    auto p3 = Max(P1, P2);

    return 0;
}

相关推荐

  1. c++11学习笔记

    2024-01-31 22:28:02       73 阅读
  2. c++学习笔记11

    2024-01-31 22:28:02       37 阅读
  3. C语言学习笔记day11

    2024-01-31 22:28:02       40 阅读
  4. C++11 thread_local学习笔记

    2024-01-31 22:28:02       38 阅读
  5. Objective-C学习笔记(NSDictionary,NSFileManager,Copy)4.11

    2024-01-31 22:28:02       34 阅读
  6. Kubernetes学习笔记11

    2024-01-31 22:28:02       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-31 22:28:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-31 22:28:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-01-31 22:28:02       87 阅读
  4. Python语言-面向对象

    2024-01-31 22:28:02       96 阅读

热门阅读

  1. nginx+ gunicorn部署flask项目

    2024-01-31 22:28:02       47 阅读
  2. 20240130

    20240130

    2024-01-31 22:28:02      52 阅读
  3. 2024.1.20 用户画像标签开发,面向过程方法

    2024-01-31 22:28:02       53 阅读
  4. 基于Qt 音乐播放器mp3(进阶)

    2024-01-31 22:28:02       52 阅读
  5. Python 因果推断(下)

    2024-01-31 22:28:02       65 阅读
  6. 【PyRestTest】基本测试集编写语法

    2024-01-31 22:28:02       66 阅读
  7. C++ 模板

    2024-01-31 22:28:02       52 阅读
  8. Redis的哨兵模式

    2024-01-31 22:28:02       49 阅读
  9. 防抖,节流

    2024-01-31 22:28:02       48 阅读