STL 线性容器 之 向量容器、向量容器迭代器

1. 成员函数

在这里插入图片描述

  • 向量只提供了尾部增加和删除
  • 容量就是最多可以放多少个。容量反应的是 向量容器维护了多少内存,大小反应的是已经占据了多少内存。

2. 初始化

在这里插入图片描述

  • 给向量后面添加新元素时,如果向量维护的内存空间满载数据,而且其后的内存空间也已经被占用,那么就会自动开辟新的足够大的连续内存空间,并把原来的数据拷贝过来(副本造副本),然后释放掉原内存空间。
  • 这个问题可以通过reserve() 提前设置向量容量来解决。
#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
class Student{
public:
    Student(string const& name = ""):m_name(name){
        cout << "缺省构造了: " << m_name << "(" << this << ")" << endl;
    }
    Student(Student const& that):m_name(that.m_name){
        cout << "用: " << that.m_name << "(" << &that << ")" << "拷贝构造了" << m_name
            << "(" << this << ")" << endl;
    }
    ~Student(){
        cout << "析构了: " << m_name << "(" << this << ")" << endl;
    }
private:
    string m_name;
};

int main(){
    vector<Student> vs;
    
    // 向量容器存的数据的副本
    // 这里的 Student("xuehui") 实例化的是一个匿名对象, 匿名对象的声明周期是当前的语句;
    vs.push_back(Student("张三"));
    vs.push_back(Student("李四"));
    getchar();
}
$ ./a.out 
# 构造匿名对象
缺省构造了: 张三(0x7ffc78ad00c0)
# 向量中存的匿名对象的副本,需要拷贝构造
用: 张三(0x7ffc78ad00c0)拷贝构造了张三(0xe8d030)
# 匿名对象被析构
析构了: 张三(0x7ffc78ad00c0)
缺省构造了: 李四(0x7ffc78ad0100)
# 李四对象存入向量时,向量维护的内存空间不够了,所有会在另外的地方开辟新的内存
用: 李四(0x7ffc78ad0100)拷贝构造了李四(0xe8d080)
# 副本造副本,因为向量维护的原来的内存空间中的数据,会被考到新维护的内存当中
用: 张三(0xe8d030)拷贝构造了张三(0xe8d060)
# 析构掉原来内存空间中的对象
析构了: 张三(0xe8d030)
# 析构匿名对象
析构了: 李四(0x7ffc78ad0100)
# 析构向量中的对象
析构了: 张三(0xe8d060)
析构了: 李四(0xe8d080)

3. 迭代器的使用

在这里插入图片描述

#include <iostream>
#include <vector>
#include <cstdio>
#include<algorithm>     // find, sort 要用
using namespace std;
class Student{
public:
    Student(string const& name = "", int age = 0):m_name(name), m_age(age){}
private:
    string m_name;
    int m_age;
    // 用友元是因为可以在外部的函数里访问类中的任何成员
    friend ostream& operator<<(ostream& os, const Student& that);
    friend bool operator==(const Student& a, const Student& b);
    friend bool operator<(const Student& a, const Student& b);
    friend bool operator>(const Student& a, const Student& b);


};


ostream& operator<<(ostream& os, const Student& that){
        os << that.m_name << ": " << that.m_age;
    }

bool operator==(const Student& a, const Student& b){
    return(a.m_age == b.m_age && a.m_name == b.m_name);
}

bool operator<(const Student& a, const Student& b){
    return(a.m_age < b.m_age);
}

bool operator>(const Student& a, const Student& b){
    return(a.m_age > b.m_age);
}

void print(string const& str, vector<Student>& v){
    cout << str << endl;
    //  IT是vector类中的迭代类的别名
    typedef vector<Student>::iterator IT;
    for(IT it = v.begin(); it != v.end(); it++){
        // it是迭代器, *it 是迭代器当前指向的节点的引用(Student类类型)
        cout << *it<<", ";
    }
    cout << endl << "-------------------------"<<endl;
   
}

class CMP{
public:
    bool operator()(Student const& a, Student const& b){
        // 这里会触发Student类的">"操作符
        return a > b;
    }
};

int main(){
    vector<Student> vs;
    vs.reserve(10);
    
    vs.push_back(Student("张三", 1));
    vs.push_back(Student("李四", 2));
    vs.push_back(Student("王五", 3));
    print("添加节点以后: ", vs);

    vs.insert(vs.begin(), Student("xuehui", 4));
    print("插入节点以后: ", vs);

    vs.erase(vs.begin());
    print("删除节点以后: ", vs);

    // IT是vector类中的迭代类的别名
    typedef vector<Student>::iterator IT;
    // it是迭代器, *it 是迭代器当前指向的节点的引用(Student类类型)
    IT it = vs.begin();
    *it = Student("赵六", 5);
    print("修改节点以后", vs);

    // find是全局域的,可以在任何一种容器中进行查找
    // 找到以后返回的是指向节点的迭代器,没有找到返回第二个参数
    // 因为find用"=="来判断两个节点是否相等, 需要Student类对象支持"=="的操作符
    IT fit = find(vs.begin(), vs.end(), Student("李四", 2));
    if(fit != vs.end()){
        cout << "找到李四" << endl;
    }

    // 用sort "<" 实现升序排序
    sort(vs.begin(), vs.end()); //sort是利用"<" 来排序的, 需要Student类对象支持"<"操作符
    print("按年龄升序排列", vs);
    // sort的比较器版本实现降序排序
    CMP cmp;
    // sort内部会触发cmp的()操作符
    sort(vs.begin(), vs.end(), cmp);
    print("按年龄降序排列", vs);

}
$ ./a.out 
添加节点以后: 
张三: 1, 李四: 2, 王五: 3, 
-------------------------
插入节点以后: 
xuehui: 4, 张三: 1, 李四: 2, 王五: 3, 
-------------------------
删除节点以后: 
张三: 1, 李四: 2, 王五: 3, 
-------------------------
修改节点以后
赵六: 5, 李四: 2, 王五: 3, 
-------------------------
找到李四
按年龄升序排列
李四: 2, 王五: 3, 赵六: 5, 
-------------------------
按年龄降序排列
赵六: 5, 王五: 3, 李四: 2, 
-------------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值