0

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

假设我有以下模板:

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?我只是将其设置为默认值吗?

4

1 回答 1

1

任何你用动态构造的东西都new需要delete在你用完后被'd'。 当它本身被破坏时,std::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被移到没关系,dbtmp本身仍然需要被delete'd。

但是,由于db不是通过 动态构造的new,因此不需要delete它。DBContainer当其拥有的对象被破坏时,它将自动被破坏。vector只有您正在构建的临时文件new需要delete'd。但即便如此,也可以通过根本不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的。您可以(并且应该)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;
};
于 2020-12-01T22:20:57.997 回答