`
kmplayer
  • 浏览: 497906 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

通用容器3_vector

阅读更多
1,vector特点:
(1)将内容放在一段连续的存储区域,索引和迭代操作非常的快.
(2)如果当前存储空间不够,需要重新分配一块更大的区域,将原来的对象拷贝到新的存储区,析构原来的对象,释放原来的内存.
Allocating a new, bigger piece of storage.
Copying all the objects from the old storage to the new (using the copy-constructor).
Destroying all the old objects (the destructor is called for each one).
Releasing the old memory.
(3)上述操作代价太大,最好预先知道需要多少个对象,然后使用reserve()预先分配大小,这样就避免了所有的拷贝和析构.
2,实例代码:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;

class Noisy
{
    static long create, assign, copycons, destroy;
    long id;
public:
    Noisy() : id(create++) //create:记录构造函数执行的次数
    {
        cout << "d[" << id << "]" << endl;
    }
    Noisy(const Noisy& rv) : id(rv.id) //copycons:记录拷贝函数执行的次数.
    {
        cout << "c[" << id << "]" << endl;
        ++copycons;
    }
    Noisy& operator=(const Noisy& rv) //assign:记录赋值操作执行的次数.
    {
        cout << "(" << id << ")=[" << rv.id << "]" << endl;
        id = rv.id;
        ++assign;
        return *this;
    }
    //容器对象,必须提供比较操作符
    friend bool operator<(const Noisy& lv, const Noisy& rv)
    {
        return lv.id < rv.id;
    }
    friend bool operator==(const Noisy& lv,const Noisy& rv)
    {
        return lv.id == rv.id;
    }
    ~Noisy() //destroy:记录析构函数调用的次数
    {
        cout << "~[" << id << "]" << endl;
        ++destroy;
    }
    friend ostream& operator<<(ostream& os, const Noisy& n)
    {
        return os << n.id;
    }
    friend class NoisyReport;
};

struct NoisyGen
{
    Noisy operator()()
    {
        return Noisy();
    }
};

//单件类,报告类的统计信息.
class NoisyReport
{
    static NoisyReport nr;
    NoisyReport() {} // Private constructor
    NoisyReport & operator=(NoisyReport &);  // Disallowed
    NoisyReport(const NoisyReport&);         // Disallowed
public:
    ~NoisyReport()
    {
        cout << "\n-------------------\n"
             << "Noisy creations: " << Noisy::create
             << "\nCopy-Constructions: " << Noisy::copycons
             << "\nAssignments: " << Noisy::assign
             << "\nDestructions: " << Noisy::destroy << endl;
    }
};
long Noisy::create = 0, Noisy::assign = 0,Noisy::copycons = 0, Noisy::destroy = 0;
NoisyReport NoisyReport::nr;

int main()
{
    freopen("main.txt","w",stdout);
    int size = 1000;
    vector<Noisy> vn;
    //vn.reserve(1200);  //有无差距很大.
    Noisy n;
    for(int i = 0; i < size; i++)
        vn.push_back(n);
    cout << "\n cleaning up"<< endl;
    return 0;
}

3,vector的内存重分配可能带来的问题:
实例代码:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;

int main()
{
    vector<int> vi(10, 0);
    ostream_iterator<int> out(cout, " ");
    vector<int>::iterator i = vi.begin();
    *i = 47;
    copy(vi.begin(), vi.end(), out);
    cout << endl;

    //强迫重新分配内存
    vi.resize(vi.capacity() + 1);
    *i = 48;  //这是i是之前的开头,不是现在的了.
    copy(vi.begin(), vi.end(), out); // No change to vi[0]
    return 0;
}

4,使用vector最有效的条件:
(1)You reserve( ) the correct amount of storage at the beginning so the vector never has to reallocate.
(2)You only add and remove elements from the back end.

5,下列代码指出了对vector进行插入和删除操作时,需要的额外代价.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;

class Noisy
{
    static long create, assign, copycons, destroy;
    long id;
public:
    Noisy() : id(create++) //create:记录构造函数执行的次数
    {
        cout << "d[" << id << "]" << endl;
    }
    Noisy(const Noisy& rv) : id(rv.id) //copycons:记录拷贝函数执行的次数.
    {
        cout << "c[" << id << "]" << endl;
        ++copycons;
    }
    Noisy& operator=(const Noisy& rv) //assign:记录赋值操作执行的次数.
    {
        cout << "(" << id << ")=[" << rv.id << "]" << endl;
        id = rv.id;
        ++assign;
        return *this;
    }
    //容器对象,必须提供比较操作符
    friend bool operator<(const Noisy& lv, const Noisy& rv)
    {
        return lv.id < rv.id;
    }
    friend bool operator==(const Noisy& lv,const Noisy& rv)
    {
        return lv.id == rv.id;
    }
    ~Noisy() //destroy:记录析构函数调用的次数
    {
        cout << "~[" << id << "]" << endl;
        ++destroy;
    }
    friend ostream& operator<<(ostream& os, const Noisy& n)
    {
        return os << n.id;
    }
    friend class NoisyReport;
};

struct NoisyGen
{
    Noisy operator()()
    {
        return Noisy();
    }
};

//单件类,报告类的统计信息.
class NoisyReport
{
    static NoisyReport nr;
    NoisyReport() {} // Private constructor
    NoisyReport & operator=(NoisyReport &);  // Disallowed
    NoisyReport(const NoisyReport&);         // Disallowed
public:
    ~NoisyReport()
    {
        cout << "\n-------------------\n"
             << "Noisy creations: " << Noisy::create
             << "\nCopy-Constructions: " << Noisy::copycons
             << "\nAssignments: " << Noisy::assign
             << "\nDestructions: " << Noisy::destroy << endl;
    }
};
long Noisy::create = 0, Noisy::assign = 0,Noisy::copycons = 0, Noisy::destroy = 0;
NoisyReport NoisyReport::nr;

int main()
{
    vector<Noisy> v;
    v.reserve(11);
    cout << "11 spaces have been reserved" << endl;
    //先构造,然后拷贝到容器,最后析构构造的对象.
    generate_n(back_inserter(v), 10, NoisyGen());

    ostream_iterator<Noisy> out(cout, " ");
    copy(v.begin(), v.end(), out);
    cout<<endl;

    cout << "Inserting an element:" << endl;
    vector<Noisy>::iterator it =v.begin() + v.size() / 2; // Middle
    //由于空间足够,插入后面的元素依次执行赋值操作.
    //最后一个元素执行复制操作.
    //新的构造对象[10]先拷贝,放入容器,然后赋值给位置的元素,所以会析构两次.
    v.insert(it, Noisy());
    copy(v.begin(), v.end(), out);
    cout << endl;

    cout << "\nErasing an element:" << endl;
    //后面的元素一次赋值给前一个元素,最后一个元素析构.
    it = v.begin() + v.size() / 2;
    v.erase(it);
    copy(v.begin(), v.end(), out);
    cout << endl;

    return 0;
}


分享到:
评论

相关推荐

    C++课程小作业-STL容器与迭代器的实现路径-设计类vector容器myVector

    1、如何实现一个类似于vector的容器myVector, 该容器能像vector一样可以实例化为存放某种数据数据的数据,并能对数据提供基本的管理, 如插入数据、删除某指定的数据、可以动态扩容、可以删除全部数据等。 2、如何...

    Generic-Container-Lib:C语言中的伪模板容器库

    通用容器库 C语言中的伪模板容器库 用法 创建或复制gcl.h。 实例化您想要使用的任何类型的模板。 // gcl.h // a vector of ints #define TYPE int // choose a type #include "gcl/vector.h" // include the header...

    C++_Iterator_迭代器_介绍

    迭代器类型提供了比下标操作更通用化的方法:所有的标准库容器都定义了相应的迭代器类型,而只有少数的容器支持下标操作。因为迭代器对所有的容器都适用,现代 C++ 程序更倾向于使用迭代器而不是下标操作访问容器...

    传智播客扫地僧视频讲义源码

    23_强化训练3_构造中调用构造(产生匿名对象)_传智扫地僧 24_new和delete的基本语法 25_new和delete的深入分析 26_静态成员变量和静态成员函数 27_C++面向对象模型初探_传智扫地僧 28_this指针 29_作业 源码及文档 01...

    Vector:C中连续的通用且可增长的数组类型-开源

    C编程语言中连续的通用且可增长的数组类型。 Vector支持分摊的固定时间元素插入和移除,以及... 这意味着通用容器需要根据客户端元素大小而不是客户端数据类型手动管理内存。 您可以在c中进行通用编程,而无需使用宏。

    STL入门快速入门教程-----学习C++

    STL重要部分,包含了许多数据结构,有vector(动态增加的数组),queue(队列),stack(堆栈)……甚至也包括string,它也可以看做为一种容器,并且适用所有的容器可用的方法。 7:算法(algorithms)部分。STL重要...

    C++ Primer中文版(第5版)李普曼 等著 pdf 1/3

    C++ Primer中文版(第5版)[203M]分3个压缩包 本书是久负盛名的C++经典教程,其内容是C++大师Stanley B. Lippman丰富的实践经验和C++标准委员会原负责人Josée Lajoie对C++标准深入理解的完美结合,已经帮助全球无数...

    cstl--国人写的挺不错的C语言通用数据结构和常用算法库,支持一个

    cstl是使用C语言编写的一个通用的数据结构和常用的算法库,它模仿SGI STL的接口和实现,支持vector, list, deque等等常用的数据结构,同时还支持排序,查找,划分等常用的算法,此外cstl也包含迭代器的类型,它作为...

    nonempty-vector:非空向量

    两组盒装向量都支持整个Vector API,并且将来计划支持非盒装,原始,可存储和通用向量。 没有尚未存在于base外部依赖项。 动机 Haskell生态系统中的每个“容器”都有一个,除了vector之外,还包括古老的。 许多...

    C++Primer(第5版 )中文版(美)李普曼等著.part2.rar

    C++ Primer中文版(第5版)[203M]分3个压缩包 本书是久负盛名的C++经典教程,其内容是C++大师Stanley B. Lippman丰富的实践经验和C++标准委员会原负责人Josée Lajoie对C++标准深入理解的完美结合,已经帮助全球无数...

    c++参考手册 2018版

    array (C++11) − vector map − unordered_map (C++11) priority_queue − span (C++20) 其他容器: 顺序 − 关联 无序关联 − 适配器 迭代器库 范围库 (C++20) 算法库 数值库 常用数学函数 特殊数学函数 ...

    C++标准程序库STL的架构

    4 通用工具 9 4.1 简介 9 4.1.1 类别 9 4.1.2 头文件 9 4.2 Pairs 9 4.2.1 简介 9 4.2.2 示例 9 4.3 auto_ptr 10 4.3.1 作用 10 4.3.2 引入原因 10 4.3.3 声明 10 4.3.4 auto_ptr拥有权的转移 10 4.3.5 示例 11 ...

    stl数据结构.docx

    C++ STL (Standard Template Library标准模板库) 是通用类模板和算法的集合,它提供给程序员一些标准的数据结构的实现,称为容器,如 queues(队列)、lists(链表)、和 stacks(栈)等。 STL容器是由一些运用最广的一些...

    C++STL程序员开发指南【可搜索+可编辑】

    3-1-3 模板参数,· · · · · · · · · ·-· · · · · · · · · ·, · · · · · · · ·......... - ............ 106 3-1-4 关键字typeruune 的使用· · · · · · · · · · · · · · ...

    -C++参考大全(第四版) (2010 年度畅销榜

    24.4 vector容器 24.5 list容器 24.6 map容器 24.7 算法 24.8 使用函数对象 24.9 string类 24.10 关于STL的最后一点说明 第三部分 标准函数库 第25章 基子C的输入/输出函数 25.1 clearerr函数 25.2 fclose函数 ...

    STL学习过程中的代码笔记

    使用容器可以方便地存储和管理数据,例如使用vector动态数组来存储元素,使用map实现键值对的映射关系等。此外,STL中的算法也让我受益匪浅。通过调用STL提供的算法函数,可以轻松地实现排序、查找、遍历等操作,极...

    C++改进退火算法解决任意规模广义旅行商问题(GTSP)

    使用C++开发,vector容器方便运行任意规模的城市,程序运行完后会保存txt文件方便查看以及绘制结果,分别为:城市坐标(x,y),最优路径,每次迭代全局最优解。提供测试数据,环形圆、阵列圆,将每个圆八等份,求...

    搜索文本文件内指定单词位置及个数(二叉平衡树c++)

    c++语言描述 搜索文本文件内指定字符位置个数。用到的数据结构有:链表,二叉平衡树。还用到了vector容器。list类和 AVL_Tree类通用性良好,可用到其他地方。

Global site tag (gtag.js) - Google Analytics