码迷,mamicode.com
首页 > 编程语言 > 详细

C++11 中值得关注的几大变化(二)

时间:2018-12-21 22:37:29      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:spl   uniq   举例   任务   收藏   derived   grok   操作   编译   

委托构造

在以前的C++中,构造函数之间不能互相调用,所以,我们在写这些相似的构造函数里,我们会把相同的代码放到一个私有的成员函数中。

class SomeType {

private:

  int number;

  string name;

  SomeType( int i, string& s ) : number(i), name(s){}

public:

  SomeType( )               : SomeType( 0, "invalid" ){}

  SomeType( int i )         : SomeType( i, "guest" ){}

  SomeType( string& s ) : SomeType( 1, s ){ PostInit(); }

};

但是,为了方便并不足让“委托构造”这个事出现,最主要的问题是,基类的构造不能直接成为派生类的构造,就算是基类的构造函数够了,派生类还要自己写自己的构造函数:

class BaseClass

{

public:

  BaseClass(int iValue);

};

 

class DerivedClass : public BaseClass

{

public:

  using BaseClass::BaseClass;

};

上例中,派生类手动继承基类的构造函数, 编译器可以使用基类的构造函数完成派生类的构造。 而将基类的构造函数带入派生类的动作 无法选择性地部分带入, 所以,要不就是继承基类全部的构造函数,要不就是一个都不继承(不手动带入)。 此外,若牵涉到多重继承,从多个基类继承而来的构造函数不可以有相同的函数签名(signature)。 而派生类的新加入的构造函数也不可以和继承而来的基类构造函数有相同的函数签名,因为这相当于重复声明。(所谓函数签名就是函数的参数类型和顺序不)

右值引用和move语义

在老版的C++中,临时性变量(称为右值”R-values”,位于赋值操作符之右)经常用作交换两个变量。比如下面的示例中的tmp变量。示例中的那个函数需要传递两个string的引用,但是在交换的过程中产生了对象的构造,内存的分配还有对象的拷贝构造等等动作,成本比较高。

void naiveswap(string &a, string &b)

{

string temp = a;

a=b;

b=temp;

}

C++ 11增加一个新的引用(reference)类型称作右值引用(R-value reference),标记为typename &&。他们能够以non-const值的方式传入,允许对象去改动他们。这项修正允许特定对象创造出move语义。

举例而言,上面那个例子中,string类中保存了一个动态内存分存的char*指针,如果一个string对象发生拷贝构造(如:函数返回),string类里的char*内存只能通过创建一个新的临时对象,并把函数内的对象的内存copy到这个新的对象中,然后销毁临时对象及其内存。这是原来C++性能上重点被批评的事。

能过右值引用,string的构造函数需要改成“move构造函数”,如下所示。这样一来,使得对某个stirng的右值引用可以单纯地从右值复制其内部C-style的指针到新的string,然后留下空的右值。这个操作不需要内存数组的复制,而且空的暂时对象的析构也不会释放内存。其更有效率。

class string

{

    string (string&&); //move constructor

    string&& operator=(string&&); //move assignment operator

};

The C++11 STL中广泛地使用了右值引用和move语议。因此,很多算法和容器的性能都被优化了。

C++ 11 STL 标准库

C++ STL库在2003年经历了很大的整容手术 Library Technical Report 1 (TR1)。 TR1 中出现了很多新的容器类 (unordered_set, unordered_map, unordered_multiset, 和 unordered_multimap) 以及一些新的库支持诸如:正则表达式, tuples,函数对象包装,等等。 C++11 批准了 TR1 成为正式的C++标准,还有一些TR1 后新加的一些库,从而成为了新的C++ 11 STL标准库。这个库主要包含下面的功能:

线程库

这们就不多说了,以前的STL饱受线程安全的批评。现在好 了。C++ 11 支持线程类了。这将涉及两个部分:第一、设计一个可以使多个线程在一个进程中共存的内存模型;第二、为线程之间的交互提供支持。第二部分将由程序库提供支持。大家可以看看promises and futures,其用于对象的同步。 async() 函数模板用于发起并发任务,而 thread_local 为线程内的数据指定存储类型。更多的东西,可以查看 Anthony Williams的 Simpler Multithreading in C++0x.

新型智能指针

C++98 的知能指针是 auto_ptr, 在C++ 11中被废弃了。C++11 引入了两个指针类: shared_ptr 和 unique_ptr。 shared_ptr只是单纯的引用计数指针,unique_ptr 是用来取代auto_ptr。 unique_ptr 提供 auto_ptr 大部份特性,唯一的例外是 auto_ptr 的不安全、隐性的左值搬移。不像 auto_ptr,unique_ptr 可以存放在 C++0x 提出的那些能察觉搬移动作的容器之中。

为什么要这么干?大家可以看看《More Effective C++》中对 auto_ptr的讨论。

新的算法

1.定义了一些新的算法: all_of(), any_of() 和 none_of()。

#include <algorithm>

//C++11 code

//are all of the elements positive?

all_of(first, first+n, ispositive()); //false

//is there at least one positive element?

any_of(first, first+n, ispositive());//true

// are none of the elements positive?

none_of(first, first+n, ispositive()); //false

2.使用新的copy_n()算法,你可以很方便地拷贝数组。

#include <algorithm>

int source[5]={0,12,34,50,80};

int target[5];

//copy 5 elements from source to target

copy_n(source,5,target);

3.可以用来创建递增的数列。如下例所示:

include <numeric>

int a[5]={0};

char c[3]={0};

iota(a, a+5, 10); //changes a to {10,11,12,13,14}

iota(c, c+3, ‘a‘); //{‘a‘,‘b‘,‘c‘}

总之,看下来,C++11 还是很学院派,很多实用的东西还是没有,比如: XML,sockets,reflection,当然还有垃圾回收。看来要等到C++ 20了。呵呵。不过C++ 11在性能上还是很快。原文还引用Stroustrup 的观点:C++11 是一门新的语言——一个更好的 C++。

如果把所有的改变都列出来,你会发现真多啊。我估计C++ Primer那本书的厚度要增加至少30%以上。C++的门槛会不会越来越高了呢?我不知道,但我个人觉得这门语言的确是变得越来越令人望而却步了。

文章就到这里了!喜欢的小伙伴关注和收藏哦~  想学C/C++的小伙伴可以加群:941636044 一起交流

 

C++11 中值得关注的几大变化(二)

标签:spl   uniq   举例   任务   收藏   derived   grok   操作   编译   

原文地址:https://www.cnblogs.com/2f3d/p/10158857.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!