c++11的新特性

c++11里面有很多的新特性,之前在项目代码中也使用过很多次,但是没有系统的整理过,在这里整理一下我特别喜欢的一些c++11的新特性,这些也是我使用频率比较高的特性嘿嘿!


auto表达式

我一般在容器迭代的时候使用auto,这样就不需要定义迭代器的类型。

for(auto it = vec.begin(); it != vec.end(); it++)
{
	cout<<*it<<endl;
}
for(auto ele:vec)
{
	cout<<ele<<endl;
}

使用nullptr而不是NULL|或者0

nullptr的基础是c++定义的一个类。
NULL在c++里面就是数字0。
NULL在纯c当中是void*。
函数可能在整型和指针型之间重载,为了避免调用到错误的函数,使用nullptr。
在这里插入图片描述
很多时候通不过编译,如果通过编译也没办法调用int*的函数,使用nullptr可以避免这个问题。

override关键字

由于子类重写父类的虚函数经常会出现错误,所以c++11加了这个override声明,子类重写父类虚函数的时候有以下的要求必须满足

  • 基类的函数必须是虚函数
  • 函数名字必须一样,析构函数除外
  • 基类和派生类的函数的参数形参必须是一致的。
  • 基类和派生类的函数常量性必须完全相同。
  • 返回值和异常必须是可以兼容的
  • 函数的引用修饰词必须完全相同。
    加入override关键字之后可以检查出为什么重载没有成功,是哪个地方出了问题。

delete关键字

有的时候,我们的类是不支持拷贝的,不支持赋值操作的,这个时候c++98的做法是将拷贝构造函数和赋值构造函数设置为private类型的,但是成员函数,友员函数还是可以访问这些函数,只是链接阶段是会报错的。
c++11提供了更好的方法,使用“=delete”来将赋值函数和拷贝构造函数设置为删除函数。这样的话无论什么函数都无法调用删除函数。
delete关键字相当于private还有一个好处是因为 private只针对于类成员函数,但是delete可以delete成员函数和普通函数。


智能指针

智能指针备注
auto_ptr可以赋值,前者失去所有权,无法放置在容器中
unique_ptr适用于专属所有权的资源,不允许拷贝,不允许赋值,转换成shared_ptr是很简单的
shared_ptr共享所有权,使用引用计数,引用计数为0的时候释放资源,问题:循环引用导致资源没有办法释放
weak_ptr配合shared_ptr使用,解决循环引用的问题,控制块当中的弱引用实现

使用智能指针需要注意以下几点

  • 拒绝使用裸指针变量(裸指针变量可能会被给到两个智能指针,二次释放等出现未定义的错误。)
  • 用make_shared来取代new出来的结果,原因如下
    (1)减少代码的冗余
//使用make_shared函数

auto p(std::make_shared<asr>());

//不使用make_shared函数

std::shared_ptr<asr> p(new asr);

(2)资源的泄漏
(3)减少一次内存的分配
std::shared_ptr p(new asr);
这个 new对象的时候要分配一次内存 构造智能指针的时候要分配控制块的内存一次,这里就涉及到了两次内存的分配。
auto p(std::make_shared());
而使用make函数可以一次分配,这样的话减少了内存的分配,可以提高性能。


move语意

move实际不做任何搬运的操作,能够实现move是因为类中重载了参数为右值引用的拷贝构造函数,而move函数做的工作就是将左值转换成右值引用,这样的话我们就会优先选择具有move语意的拷贝构造函数!!!
具有move语意的拷贝构造函数实际上没有做深拷贝的动作,而是通过交换指针来将右值的东西偷走。

左值和右值

  • 右值是指只能在等式右边的值,而左值是指可以在等式左边和等式右边的值。
  • 右值一般指的是匿名对象和临时值,通常是字面量(数字、字符串)、临时对象或者表达式,类似于2*10Demo()这种。而左值指的是有名的变量和有名的对象。
  • 生命周期 对于左值而言,语句之外还存在 而对于右值而言 语句之外就不存在了。
  • 取地址操作 左值是可以取地址的,但是右值是不可以取地址的 但是字符串字面量除外 &“abc”是可以取到地址的 但是字符串常量是左值!!!

左值引用 右值引用

  • 在c++11之前的概念当中,没有右值引用的概念,引用的话只代表左值引用,那个时候就出现了问题。
    如下图所示:
    在这里插入图片描述
    这个时候我们发现这个函数是没发打印出abc字符串在这里插入图片描述字面量的。
    自定义对象的时候也会出现这个问题。
    在这里插入图片描述
    因为这个时候我们的函数是接受左值引用的,但是构造的匿名对象是右值,所以没办法正常调用函数。

那么,之前为什么很多应用过程中没有大规模的出现这个问题?
因为C++对const&添加特殊技能:既能接受左值又能接受右值。上面两个例子把函数参数加上const,即void Print(const string& s)和void Func(const Demo &),问题解决了。
void Func(const Demo &)类型匹配解决了,为什么void Print(const string& s)也可以了呢?因为编译器自动把根据函数参数类型string,自动为"abc"构造一个临时对象string(“abc”),这是默认类型转换。

  • 后来c++11中引入了右值引用,&&来和const &区分开来,因为const&虽然可以接受右值引用了,但是却限制了修改,传入的对象是不能修改的。

看下面这段代码

#include <iostream>
using namespace std;

class Demo{};
void Func(const Demo &){
  cout << "Func(const Demo &)" << endl;
}

void Func(Demo &){
  cout << "Func(Demo &)" << endl;
}

void Func(Demo &&){
  cout << "Func(Demo &&)" << endl;
}

int main(){
    Demo d;
    Func(d);
    Func(Demo());
    const Demo cd;
    Func(cd);
}

运行结果如下:

Func(Demo &)
Func(Demo &&)
Func(const Demo &)

但是我们为了支持一个接口可以传递左值引用,也可以传递右值引用,需要重载函数,这样的话未免太麻烦了 所以c++11又引入了一个新的特性,叫做完美转发

完美转发

&&在模板参数中表示万能引用,在非模板参数中表示右值引用。
看下面这段代码

#include <iostream>
using namespace std;

class Demo{};
template<typename T> 
void Func(T &&){
  cout << "Func()" << endl;
}
int main(){
    Demo d;
    Func(d);
    Func(Demo());
    const Demo cd;
    Func(cd);
}

运行结果如下

Func()
Func()
Func()

这样就可以解决不用写那么多函数的问题啦!!!!
当传入右值时,模板特化成void Func(T &&),当传入左值时,模板特化成void Func(T &)。瞬间解决上面的问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++11引入了许多新特性,其中包括线程池的实现。在引用中的代码中,ZERO_ThreadPool类封装了线程池的功能。线程池的原理是通过维护一个线程队列和一个任务队列来实现的。 在初始化阶段,通过调用init函数来初始化线程池。该函数会创建指定数量的线程,并将其保存在threads_队列中。如果线程池已经被初始化过,则直接返回false。 在启动线程池后,调用start函数。该函数会循环创建指定数量的线程,并将它们放入threads_队列中。每个线程都会调用run函数来执行任务。 当调用exec函数时,会将任务添加到tasks_队列中。其中,std::bind用于绑定一个成员函数和其参数,以及占位符std::placeholders::_1表示传入的参数。 在waitForAllDone函数中,会判断atomic_是否为0且tasks_是否为空。如果是,则表示所有任务已经执行完毕,线程池可以退出。 线程池的stop函数用于停止线程池的运行。它会遍历threads_队列,并调用每个线程的join函数,等待线程执行完毕后再返回。 以上就是C++11新特性线程池的基本原理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [基于C++11新特性手写线程池实现](https://blog.csdn.net/m0_70418130/article/details/126805390)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值