我应该如何在构造函数中管理 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
动态构建的任何内容在您使用完后都需要 delete
。 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
的内容移到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;
};
我正在学习内存管理,不太确定如何管理删除 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
动态构建的任何内容在您使用完后都需要 delete
。 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
的内容移到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;
};