c++11学习笔记

本文概述了C++中关键的编程概念,如线程同步(互斥锁、条件变量、threadsafe_queue)、函数和模板的使用,包括运算符重载、auto、decltype、右值引用、函数对象、std::bind等。还讨论了智能指针和可变参数模板等C++11新特性及其应用。
摘要由CSDN通过智能技术生成

收集

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();

}

};

重载操作符operator

常见的三种用法

1,重载运算符“±*/=”等

2,重载函数调用运算符

3,类型转换运算符

#include <iostream>

class MyNumber {
private:
  int value;

public:
  MyNumber(int num) : value(num) {}

  int getValue() const {
    return value;
  }

  // 重载加法运算符 '+'
  MyNumber operator+(const MyNumber& other) {
    int sum = value + other.value;
    return MyNumber(sum);
  }
};

int main() {
  MyNumber num1(5);
  MyNumber num2(10);

  MyNumber sum = num1 + num2;  // 使用重载的加法运算符进行相加操作

  std::cout << "Sum: " << sum.getValue() << std::endl;

  return 0;
}
class Adder {
public:
  //重载函数调用
  int operator()(int a, int b) {
    return a + b;
  }
};
// 使用函数对象进行加法运算
Adder add;
int result = add(3, 4);  // 调用 operator(),返回结果 7
class MyType {
public:
	using fr_t = void(*)(int);
	static void func(int a)
	{
		std::cout << "the value:" << a << std::endl;
	}
	operator fr_t() {
	// 执行适当的转换操作
	// 将 MyType 转换为 fr_t
	return func;//这里是将函数指针赋给了fr_t
  }
};

// 使用类型转换运算符进行类型转换
MyType obj;
obj(2);  // 这里涉及到两步动作:一是调用 operator fr_t(),将 obj 转换为 fr_t 类型;二是调用了fr_t(2)

auto、decltype

右值引用

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;
}

智能指针模板

参考:C++:共享指针shared_ptr的理解与应用-CSDN博客

可变参数模板

参考:C++11实用技术(五)泛型编程加载dll接口函数_c++ 加载dll-CSDN博客

文章参考,侵删

C++11实用技术(一)auto与decltype的使用_c++11 auto decltype 实际应用-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值