【问题标题】:Destroying a vector of vectors销毁向量的向量
【发布时间】:2018-07-03 00:15:55
【问题描述】:

我正在研究一个 Matrix 类,该类是用一个向量实现的,如下所示:

class Matrix {
    private:
        int r, c;
        std::vector<std::vector<double> > grid;
    public:
        //things

目前我正在实现析构函数,并对此进行了思考。在我(聪明地)切换到std::vector 之前,我使用的是double ** grid。这意味着相当多的new 调用,因为每个指针都指向一个数组(这也是我相信的指针......或者我遇到的错误无论如何都暗示......)。无论如何,析构函数看起来像:

Matrix::~Matrix() {
    for (int i = 0; i < r; i++) {
        delete [] grid[i]
    delete [] grid

现在我正在尝试复制它(也许是不必要的?)并拥有以下内容:

Matrix::~Matrix() {
    std::vector<std::vector<double> >::iterator it = this->grid.begin();
    for (it; it != this->grid.end(); it++) {
       (*it).clear()
    this->grid.clear();
    std::vector<std::vector<double> >().swap(this->grid);

Matrix::~Matrix() {
    this->grid.clear();
    std::vector<std::vector<double> >().swap(this->grid);

我倾向于使用后者,因为clear() 应该完全破坏内部向量(不仅仅是内部向量的内容),然后 复制和交换 idiom-ish 效果临时向量以释放原始外部向量的内存。前者让我认为我 clear() 每个内部向量的内容,但留下了 n 个空的、仍在内存中的向量,并且必须在每个向量上调用临时交换机制(因此可能 [未经测试] 影响我的迭代器)。

在外部向量上调用clear() 是否通过调用它们的析构函数来完全释放用于内部向量的内存?我不确定他们的析构函数是否以交换习语的方式释放。

【问题讨论】:

  • 不用了,所有的vector都有自己的析构函数。
  • 不需要你写析构函数。
  • 向量会自我毁灭。无事可做。
  • big 3 背后的指导方针是,如果您需要定义一个(复制 ctor、复制分配或析构函数),您可能需要另外 2 个,而不是您应该始终定义所有三个。跨度>
  • 并添加到@BenjaminLindley:现在您的所有成员都是自我清洁的(因此您没有手动管理的资源),您可能不需要 任何 大3;不定义它们,编译器将为您正确生成所有它们(在 C++11 及更高版本下,移动构造函数和移动赋值运算符也是如此),您无需付出任何努力。比这里的 3 规则更重要的是 the rule of 0

标签: c++ vector


【解决方案1】:

注意,这个析构函数比你想象的要复杂。我们开始:

好吧,其实不是。您可以感谢rule of zero 的这种灵活实现。由于std::vector 是一个行为良好的类(模板),它通过RAII 正确管理其资源,因此为您的类默认生成的析构函数可以在您不输入任何内容的情况下执行正确的操作。

如果出于任何原因,您仍需要该析构函数的显式签名,则可以在类中使用以下语法:

~Matrix() = default;

或者,如果您需要定义外联,则正常声明析构函数,但要这样定义:

Matrix::~Matrix() = default;

【讨论】:

    【解决方案2】:

    您不需要编写显式析构函数。当您超出此 2D 矢量定义的范围时,默认析构函数序列将处理破坏部分。 2D向量的每个元素都是1D向量,1D向量的每个元素都是double,所以默认的销毁顺序会先销毁grid[0],如下图,依次销毁存储在grid中的每个double元素[0],之后它将对 grid[1] 重复相同的操作,依此类推。

                                           _____  
                 _____ grid[0] of doubles |_|_|_|....
                |_____ grid[1] of double
        grid--> |_____ grid[2] of double
                |_____ grid[3] of double
                |_____ grid[4] of double
    

    【讨论】:

      猜你喜欢
      • 2023-04-01
      • 2013-05-24
      • 2020-01-10
      • 2012-01-16
      • 1970-01-01
      • 2022-01-06
      • 2012-12-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多