C++ 手记(二):C++ 11新增的好用feature

本文汇总了C++11一些实用特性。包括构造函数的委托和继承,可简化代码、节省目标代码空间;新增std::array等容器,各有性能特点;还涉及std::function、lambda表达式、右值引用和move语义、std::mutex等内容,部分可参考之前文章。

【声明】:本文为网络和个人学习总结汇总,方便查阅!

除了前文已经提到了extern外部模板,lambda表达式以外,还有一些比较好用feature:

构造函数(委托和继承)

委托构造

C++11 引入了委托构造的概念,这使得构造函数可以在同一个类中一个构造函数调用另一个构造函数,从而达到简化代码的目的:

class Base {
public:
    int value1;
    int value2;
    Base() {
        value1 = 1;
    }
    Base(int value) : Base() {  // 委托 Base() 构造函数
        value2 = 2;
    }
};

继承构造

在继承体系中,如果派生类想要使用基类的构造函数,需要在构造函数中显式声明

struct A
{
  A(int i) {}
  A(double d,int i){}
  //...等等系列的构造函数版本
}struct B:A
{
  B(int i):A(i){}
  B(double d,int i):A(d,i){}
  //......等等好多个和基类构造函数对应的构造函数
}

而在c++11中:

struct B:A
{
  using A::A;
  //关于基类各构造函数的继承一句话搞定
  //......
}

直接using A::A;就可以使用基类的所有构造函数了,更重要的是,如果其中某一个继承构造函数不被相关的代码使用,编译器不会为之产生真正的函数代码,这样比透传基类各种构造函数更加节省目标代码空间。

新增容器

  • std::array
    std::array 保存在栈内存中,相比堆内存中的 std::vector,能够灵活的访问这里面的元素,从而获得更高的性能。
std::array<int, 2> arr = {1,2};

// 显式转换指针有两种方式
&arr[0];
arr.data();
  • std::forward_list
    std::list 的双向链表的实现不同,std::forward_list 使用单向链表进行实现,提供了 O(1) 复杂度的元素插入,不支持快速随机访问(这也是链表的特点),也是标准库容器中唯一一个不提供 size() 方法的容器。当不需要双向迭代时,具有比 std::list 更高的空间利用率。
  • 无序容器
    C++11 引入了两组无序容器: std::unordered_map/std::unordered_multimapstd::unordered_set/std::unordered_multiset
    无序容器中的元素是不进行排序的,内部通过 Hash 表实现。
  • 元组 std::tuple
    元组的使用有三个核心的函数:
    • std::make_tuple: 构造元组 auto student = std::make_tuple(3.8, 'A', "张三");
    • std::get: 获得元组某个位置的值 double gpa = std::get<0>(student)
    • std::tie: 元组拆包 std::tie(gpa, grade, name) = student;

std::function

关于这部分内容可以参考之前的文章:
C++11:std::function<void()> func;

lambda表达式

可以参考之前的文章:
C++11:Lambda表达式

右值引用和move语义

可以参考之前的文章:
C++11:左值、右值、左值引用、右值引用有什么区别?
C++11:移动语义Move Semantics和完美转发Perfect Forwarding

这里再补充理解一下:

string a(x);    
string b(x + y);        

我们知道上边两行是要走拷贝构造函数:

string(const string& that) {
    size_t size = strlen(that.data) + 1;
    data = new char[size];
    memcpy(data, that.data, size);
}

这里第一行是有必要做一次深拷贝的,因为x是一个左值,其他地方还可能会用到这个x。但是第二个就完全没有必要做深拷贝,因为x+y是一个右值,后边不能使用到这个值,这样就造成了资源的浪费。为了解决这个问题,就用了右值引用,相当于延长了右值的生命周期,这里再写一个移动构造函数——“带右值引用的拷贝构造”:

string(string&& that) {   // string&& is an rvalue reference to a string
data = that.data;
that.data = 0; // 把源对象指针置空
}

另外对于赋值操作符,在c++11中,编译器会依据参数是左值还是右值在拷贝构造函数和移动构造函数间进行选择。

std::mutex

这部分可以参考之前的文章:
C++11:互斥锁std::mutex和std::lock_guard/std::unique_lock

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值