stl中copy代码分析

2017-10-16  本文已影响0人  lwj_ow

开学了,乱七八糟的事情比较多,时间也比较零散,这几天刚把stl源码剖析看完,想先简单分析一下copy的代码,其中做了很多优化,值得稍微分析一番.

image.png
  1. 这个图首先总括了copy的设计思路,针对各种情况做出了优化.
    首先就是针对char类型的拷贝,我们直接使用了底层的memmove,这是内存底部操作,速度非常的快.
    其次是泛化,再针对原生指针做出特化,如果指针所指对象拥有的是trivial assignment operator,复制操作可以不通过它(也就是ctor),也就是说我们直接用memmove来完成拷贝.如果对于原生指针,它指向的对象拥有的是non-trivial assignment operator,我们就使用for循环来慢慢拷贝了.
    不过值得一提的是,如果迭代器不是随机存取迭代器的话,我们在for循环中判断条件就只能使用first!=last来判断了(否则我们可以使用两个迭代器之间的距离来作为循环判断条件了,因为这样速度会快点).
    这个大概就是copy的主要思路,下面来仔细分析一下.

  2. 首先看看我们copy的对外接口:


    image.png

    接下来是两个多载函数,针对原生指针(可视为一种特殊的迭代器)const char*和const wchar_t *,进行内存直接拷贝操作.


    image.png
    这个就是特化版本,,针对原生指针类型的重载,这个对拷贝效率的提升是巨大的.
    接下来是个完全泛化的版本和两个偏特化版本.
    image.png

    主要是针对原生指针类型进行了偏特化.下面讲的是这两个偏特化版本.这两个偏特化版本在参数为原生指针的情况前提下,进一步判断指针所指向之物是否具有trivial assignment operator(平凡赋值操作符).这个东西我在博客的后面再来简单说一下,这里不细说,大概意思就是如果指针指向的对象具有trivial assignment operator,我们就直接使用内存拷贝(memmove)来进行拷贝,大大增加了效率,如果不具有的话,我们就正常通过assignment operator来进行赋值.下面是代码:


    image.png
    下面我们看一下完全泛化的版本针对迭代器的种类编写的两个版本.
    image.png
    这个的主要区别在于for循环的条件判断.我们在上面已经介绍过了,不再多说.
  3. 下面我们介绍一下trivial assignment operator.
    先从字面意思上来看,trivial的意思就是琐碎的,无关紧要的.所以,我们大概可以认为这个赋值运算符基本啥都没做,仅仅拷贝内存.所以我们可以使用memmove来进行替代,不需要进行其他繁琐的函数调用了.
    这个是和我们的constructor也是联系起来的,如果constructor是trivial的,那么我们的assignment operator就是trivial的.不过值得一提的是,我们自己定义的类,都不是trivial constructor,这里我在网上Google了一番,stackoverflow上有个回答我贴上来.What is a non-trivial constructor in C++?
    这个说的还是挺清楚的.

结语:这个对copy的分析不是很难,主要是实现方面的细节,对各种能优化的情况都进行了优化,后面stl里面的sort算法也是这样,极尽优化.后面我们再分析一下sort算法.

上一篇 下一篇

猜你喜欢

热点阅读