C++ STL/ (9) STL容器中数据的传递

我们在前面讲了stl中常见的容器:顺序容器(string,vector,deque,stack,queue,list)和关联式容器(set,map)。
本节主要讨论一下,以上各种容器中,数据是如何传递的。

数据的传递的方式主要有一下几种:

  • 传值:一份数据,进行值传递,会在内存空间上开辟多份存储空间。涉及拷贝操作。
  • 传指针:传递的是数据的地址,不涉及拷贝操作。
  • 传引用:跟传指针一样。

STL中数据是以值的方式进行传递的,STL中的元素对象都要能够拷贝,否则无法插入STL容器中。谈到拷贝,那么不可避免的要讨论一下深拷贝浅拷贝的问题。

我们先来看一段代码:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Teacher{
public:
    int age;
    char * name;
    Teacher(char *name, int age){
        int len = strlen(name) + 1;
        this->name = new char[len];
        strcpy(this->name, name);
        this->age = age;
    }

    ~Teacher(){
        if (this->name != NULL){
            delete[] this->name;
        }
        this->age = 0;
    }


};

void test(){
    Teacher t1("aaa", 1), t2("bbb", 2);
    vector<Teacher> v;
    v.push_back(t1);
    v.push_back(t2);

}
int main(){

    test();
    return 0;
}

思考一下,这段代码为什么出错了?
因为C++ STL中的copy是浅copy。只拷贝的字符指针name,却没有copy字符指针所指向的堆内存空间
。所以在程序结束的时候,vector容器中的两个Teacher对象释放了name指针所指向的堆内存空间,轮到对象t1和t2释放name所指向的内存空间时,发现找不到该内存空间了。于是程序崩溃。

解决方法就是重载拷贝构造函数和运算符=。将字符指针name所指向的堆内存空间也拷贝过来。
代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Teacher{
public:
    int age=0;
    char * name="aiden";
    Teacher(char *name, int age){
        int len = strlen(name) + 1;
        this->name = new char[len];
        strcpy(this->name, name);
        this->age = age;
    }

    Teacher(const Teacher & t){
        int len = strlen(t.name) + 1;
        this -> name = new char[len];
        strcpy(this->name, t.name);
        this->age = t.age;
    }

    Teacher& operator=(Teacher &t){
        int len = strlen(t.name) + 1;
        this->name = new char[len];
        strcpy(this->name, t.name);
        this->age = t.age;
        return *this;
    }


    ~Teacher(){
        if (this->name != NULL){
            delete[] this->name;
        }
        this->age = 0;
    }


};

void test(){
    Teacher t1("aaa", 1), t2("bbb", 2);
    vector<Teacher> v;
    v.push_back(t1);
    v.push_back(t2);
    vector<Teacher>::iterator i = v.begin();
    while (i != v.end()){
        cout << "Teacher's name is: " << i->name << " " << "Teacher's age is: " << i->age << endl;
        i++;

    }
    cout << endl;
}
int main(){

    test();
    return 0;
}

版权声明:本文为anran_zhou原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。