我应该如何在构造函数中管理 moving/swapping 之后的中间向量?

How should I manage an intermediary vector after moving/swapping it in the constructor?

我正在学习内存管理,不太确定如何管理删除 and/or 析构函数策略。

假设我有以下模板:

template <typename X>
class DBContainer {
private:
  vector<vector<X>> db;
  size_t dbSize;

public:
  DBContainer(size_t n = 100) {
    dbSize = n;
    <vector<vector<X>> *tmp = new vector<vector<X>>(dbSize);
    db = std::move(*tmp);
    // db = std::swap(tmp);
    delete tmp;
  }

  ~DBContainer() { /* how should I delete `db`? */ }
  // ~DBContainer() = default;
};

我应该如何设置 db 的析构函数策略?据我所知,对于原始指针,std::move 仅将向量的中间向量复制到 db;因此,我仍然需要删除中间动态分配的向量。我可能是错的,但我相信 std::swap.

也是一样的

但是,在程序结束时,我应该如何管理 db 的析构函数策略?我只是将其设置为默认值吗?

您使用 new 动态构建的任何内容在您使用完后都需要 deletestd::unique_ptr 可以通过在它自身被破坏时为您调用 delete 来帮助解决这个问题,例如:

template <typename X>
class DBContainer {
private:
  vector<vector<X>> db;
  size_t dbSize;

public:
  DBContainer(size_t n = 100) {
    dbSize = n;
    std::unique_ptr<vector<vector<X>>> tmp(new vector<vector<X>>(dbSize));
    // or: auto tmp = std::make_shared<vector<vector<X>>>(dbSize);
    db = std::move(*tmp);
  } // <-- tmp is destroyed here, delete'ing the temp vector

  //~DBContainer() = default;
};

tmp内容移到db没关系,tmp本身还是要delete'd.

但是,由于 db 不是通过 new 动态构建的,因此没有必要 delete 它。当它拥有的 DBContainer 对象被销毁时,它将被自动销毁。只有通过 new 构建的临时 vector 需要 delete。但即便如此,也可以通过根本不动态构建临时 vector 来避免,例如:

template <typename X>
class DBContainer {
private:
  vector<vector<X>> db;
  size_t dbSize;

public:
  DBContainer(size_t n = 100) {
    dbSize = n;
    vector<vector<X>> tmp(dbSize);
    db = std::move(tmp);
  } // <-- tmp is destroyed here

  //~DBContainer() = default;
};

或者:

template <typename X>
class DBContainer {
private:
  vector<vector<X>> db;
  size_t dbSize;

public:
  DBContainer(size_t n = 100) {
    dbSize = n;
    db = vector<vector<X>>(dbSize); // <-- temp destroyed after operator= exits
  }

  //~DBContainer() = default;
};

也就是说,您实际上根本不需要临时 vector。您可以(并且应该)在构造函数的 member initialization list 中直接初始化 db,例如:

template <typename X>
class DBContainer {
private:
  vector<vector<X>> db;
  size_t dbSize;

public:
  DBContainer(size_t n = 100) : db(n), dbSize(n) { }

  //~DBContainer() = default;
};

从技术上讲,您也可以去掉 dbSize,只需在需要时使用 db.size()

class DBContainer {
private:
  vector<vector<X>> db;

public:
  DBContainer(size_t n = 100) : db(n) { }

  //~DBContainer() = default;
};