C ++中的std :: vector到底是什么?

时间:2014-08-10 06:36:31

标签: c++ vector stl

到目前为止,我发现,我完全不了解std :: vector的本质。

让我解释一下:

矢量是可以增长的,对吗?这意味着,在内部它必须以某种方式动态分配/重新分配内存。像这样:

class vector {
private:
    int *data;
};

好。但是这样的定义意味着如果我们通过引用或值将std :: vector传递给另一个函数 - 这两种类型的参数传递之间没有区别,并且两个函数都能够修改数据(除非vector是作为const传递。

BUT!我尝试了以下内容,但我的想法失败了:

void try_to_modify(vector<int> v) {
    v[2] = 53;
}

int main() {
    vector<int> v(3);
    v[2] = 142;
    try_to_modify(v);
    cout << v[2] << '\n';    // output is: 142

    return 0;
}

那么真相在哪里? std :: vector到底是什么?

谢谢。

2 个答案:

答案 0 :(得分:7)

std :: vector是一个容器,它在内部管理其内存并提供自定义复制构造函数。在此复制构造函数中,将分配新内存并复制现有数据,这使其成为一项昂贵的操作。如果要传递矢量而不复制包含的数据,可以传递const引用,例如const std::vector<int>&

让我们看看如何实现像std :: vector这样的基本容器。

template <typename T>
class MyVector
{
public:
    MyVector (int size)
    : data_ (new T[size])
    , size_ (size)
    {}

    ~MyVector ()
    {
        delete [] data_;
    }

 private:
    T* data_ = nullptr;
    int size_ = 0;
};

如果我们复制这样的对象,我们就会遇到两个问题。首先,正如您所注意到的,内存将指向相同的位置。其次,我们将有两个析构函数将破坏相同的内存,从而实现双重释放。所以,让我们添加一个复制构造函数,每当复制时都会调用它。

MyVector (const MyVector& other)
: size_ (other.size_)
{
    data_ = new T[size_];
    std::copy (other.data_, other.data_ + size_, data_);
}

MyVector& operator= (const MyVector& other)
{
    // allocate and copy here to allow for self-assignment
    auto newData = new T[other.size_];
    std::copy (other.data_, other.data_ + size_, newData);

    delete [] data_;

    size_  = other.size_;
    data_ = newData;

    return *this;
}

那就是std::vector内部如何运作。

答案 1 :(得分:-1)

这对于vector来说不是一个问题,因为它是pass-by-value和pass-by-reference参数。

void try_to_modify (vector<int> vec)会将原始矢量的副本发送给该函数,该函数将在副本上运行。矢量将在复制时复制数据。即指向新数据的新指针。

但是,如果您将函数定义为:void try_to_modify(vector<int> & vec),那么它会将精确向量发送到函数,您的函数将对其进行操作。

通过引用传递对象来说要快得多,并且通常更可取,除非您特别需要副本。