`
kmplayer
  • 浏览: 509874 次
  • 性别: 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;
}


分享到:
评论

相关推荐

    cPP.rar_c++ 容器使用_容器

    - **算法(Algorithms)**:STL还提供了一系列通用算法,如sort、find、transform等,可以方便地应用于任何容器,极大地提高了代码的可重用性和效率。 - **RAII(Resource Acquisition Is Initialization)**:C++...

    STL标准模板库vector容器

    迭代器是容器与算法之间的桥梁,提供了访问容器中元素的通用方法。迭代器的种类很多,包括输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器。迭代器提供了移动和访问容器中元素的能力,可以看作是...

    cuda thrust 文档

    Thrust 提供了多种容器类型,其中最常用的是 `host_vector` 和 `device_vector`,它们分别用于主机和设备端数据管理。 ##### 示例代码解析 ```cpp #include &lt;thrust/host_vector.h&gt; #include &lt;thrust/device_vector...

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

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

    容器通用算法和迭代器

    STL中的通用算法是一系列独立于容器的函数,可以用于处理各种容器内的元素。常见的通用算法有: 1. `std::sort`:对容器内的元素进行排序。 2. `std::find`:查找容器中是否存在特定元素。 3. `std::count`:统计...

    STL vector:在Matlab中对STL vector容器的模仿。-matlab开发

    STL(Standard Template Library,标准模板库)是C++中的一部分,它提供了一组高效、通用的容器和算法。在本场景中,我们关注的是STL中的`vector`容器,这是一个动态数组,允许在任意位置插入和删除元素,并且其大小...

    STL容器 内容全,讲解详细 包括Vector、Deque、sort、set、map等

    3. **String**:虽然String在C++中被视为一种特殊的容器,但它同样属于STL的一部分。String可以用来存储和操作字符序列,提供了类似文本处理的各种功能,如查找、替换、拼接等。与C风格的字符数组相比,String更加...

    C语言里的通用算法介绍

    根据给定的信息,我们可以深入探讨C语言中的通用算法及其应用方式。尽管提供的部分内容存在乱码问题,但结合标题、描述及部分可辨识的内容,我们可以围绕C语言算法展开讨论。 ### C语言里的通用算法介绍 #### 算法...

    Thrust CUDA介绍PPT

    此外,Thrust 容器与 STL 容器兼容,这意味着可以轻松地在 Thrust 容器和标准库容器之间转换,如将 `std::list` 转换为 `thrust::device_vector`。这种兼容性降低了学习曲线,使得熟悉 C++ STL 的开发者能更快地上手...

    C++顺序容器,容器适配器,关联容器的操作

    本文将详细介绍几种常见的顺序容器,包括`vector`、`string`、`list`、`forward_list`、`deque`以及`array`,并且探讨这些容器的初始化、赋值、大小调整、元素添加与删除等基本操作。 #### 二、顺序容器详解 ##### ...

    C++ STL find_if使用的一个完整例子

    在提供的`Test_stl_find`文件中,我们可以假设它包含了一个示例,展示如何使用`find_if`找到容器(如vector、list或array)中第一个满足特定条件的元素。由于没有具体的代码示例,我将给出一个通用的例子来说明`find...

    对一组vector对象,计算相邻元素的和

    #### 一、C++标准库中的`vector`容器 `vector`是C++标准模板库(STL)中的一个非常重要的容器类。它支持动态数组的功能,能够存储相同类型的元素,并且可以自动管理内存,提供灵活的数据操作方法。 - **特点**: - ...

    二维vector.docx

    `sort`函数是C++标准库中的一个通用排序算法,可以用于对容器中的元素进行排序。 - **按第一关键字升序排序**: ```cpp sort(A.begin(), A.end()); ``` 这会按照第一列的值对二维`vector`的每一行进行升序排序...

    Java容器集合(equals 和 hashCode+基础数据结构+ArrayList+Vector和LinkedList)

    Java容器集合(equals和hashCode+基础数据结构+ArrayList+Vector和LinkedList) Java容器集合是Java中的一种基础数据结构,用于存储和管理数据。其中,equals和hashCode方法是Java容器集合中两个非常重要的方法,...

    标准库STL_第1节_顺序容器

    在实际编程中,我们还需要理解迭代器的概念,它是访问容器中元素的通用接口。STL中的迭代器分为输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器,不同类型的迭代器支持的操作不同。例如,只有随机...

    STL容器和算法函数表

    STL不仅提供容器,还有一系列通用算法,如`sort`, `find`, `copy`, `transform`等,这些算法可以作用于任何满足一定要求的序列上,极大提高了编程效率和代码的可读性。例如: - `sort`: 对容器进行排序。 - `find`: ...

    vector介绍(buiW)

    在C++标准库中,`std::vector`是实现这一概念的容器,但在给定的描述中,我们看到的是一个自定义的`Vector`结构体,用于存储和管理一系列`void*`类型的指针。下面我们将详细讨论这个自定义`Vector`的数据结构以及其...

    Vector用 法 简 述

    C++标准库为每种标准容器定义了一种迭代器类型,这些迭代器类型提供了比简单的下标操作更为通用的方法来访问容器元素。尽管`vector`支持下标操作,但在现代C++编程实践中,更倾向于使用迭代器来访问元素,以确保代码...

    容器读取三维点数据代码

    - **存储数据到容器**:使用`std::vector`容器存储每一个读取到的`Vector3d`对象。 - **遍历输出**:最后,使用`for`循环遍历`std::vector`容器中的每一个`Vector3d`对象,并调用其输出函数来显示三维点数据。 ##...

Global site tag (gtag.js) - Google Analytics