当 class 包装了一个 STL 容器和一个指针时,我是否应该在我的 class 的析构函数中销毁 STL 容器?
Should I destroy STL containers in my class's destructor, when the class wraps both a STL container and a pointer?
我有点理解这样一个事实,即 class 的包装 STL 容器将在 class 的实例超出范围时自动销毁。因此,当 class 仅包装 STL 容器时,我不必编写析构函数。但是,如果 class 还必须管理一些指针怎么办?
说在某些 CUDA 开发中,我想要一个 class 来处理设备指针和 STL 容器。
class Image{
private:
float *data_device;
std::array<int, 2> shape;
public:
// some constructors and methods
~Image(){
cudaFree(data_device);
// what to do with the STL array?
}
};
在上面的例子中,我需要析构函数来释放 data_device
的内存。但是我应该处理 STL 数组吗?如果是这样,我怎样才能正确销毁 shape
?
But should I deal with the STL array?
不,你不应该。
std::array
析构函数自动销毁数组的每个元素。
你创建一个析构函数来手动拆除你 class 管理的任何东西是正确的。
但是,这样做并不能阻止其他一切被破坏。在 析构函数运行后,您的成员仍将被自动析构;你的析构函数是另外。
所以你做对了。
您可以想象,析构函数的右大括号还调用了每个成员(和基类)的析构函数,调用顺序与构造函数相反。
因此,您无需对设计合理的成员执行任何额外操作,所有 std
容器都是如此。但是让我们后退一点。
But what if the class also have to manage some pointer(s)?
你不应该写这样的class。相反,您使用 class 的 唯一 工作是管理 恰好一个 指针作为 "some pointer" 的替代方法。作为奖励,您现在不必担心 double-free,因为 Image
没有默认的复制构造函数
// cuda Deleter for std::unique_ptr
struct CudaFree
{
void operator()(float * ptr) { cudaFree(ptr); }
}
class Image{
private:
std::unique_ptr<float, CudaFree> data_device;
std::array<int, 2> shape;
public:
Image(/* ? */)
: data_device(cudaAlloc()/* ? */),
shape(/* ? */)
{/* ? */}
// similarly other constructors
// other members
// implicit destructor does the right thing
};
我有点理解这样一个事实,即 class 的包装 STL 容器将在 class 的实例超出范围时自动销毁。因此,当 class 仅包装 STL 容器时,我不必编写析构函数。但是,如果 class 还必须管理一些指针怎么办?
说在某些 CUDA 开发中,我想要一个 class 来处理设备指针和 STL 容器。
class Image{
private:
float *data_device;
std::array<int, 2> shape;
public:
// some constructors and methods
~Image(){
cudaFree(data_device);
// what to do with the STL array?
}
};
在上面的例子中,我需要析构函数来释放 data_device
的内存。但是我应该处理 STL 数组吗?如果是这样,我怎样才能正确销毁 shape
?
But should I deal with the STL array?
不,你不应该。
std::array
析构函数自动销毁数组的每个元素。
你创建一个析构函数来手动拆除你 class 管理的任何东西是正确的。
但是,这样做并不能阻止其他一切被破坏。在 析构函数运行后,您的成员仍将被自动析构;你的析构函数是另外。
所以你做对了。
您可以想象,析构函数的右大括号还调用了每个成员(和基类)的析构函数,调用顺序与构造函数相反。
因此,您无需对设计合理的成员执行任何额外操作,所有 std
容器都是如此。但是让我们后退一点。
But what if the class also have to manage some pointer(s)?
你不应该写这样的class。相反,您使用 class 的 唯一 工作是管理 恰好一个 指针作为 "some pointer" 的替代方法。作为奖励,您现在不必担心 double-free,因为 Image
没有默认的复制构造函数
// cuda Deleter for std::unique_ptr
struct CudaFree
{
void operator()(float * ptr) { cudaFree(ptr); }
}
class Image{
private:
std::unique_ptr<float, CudaFree> data_device;
std::array<int, 2> shape;
public:
Image(/* ? */)
: data_device(cudaAlloc()/* ? */),
shape(/* ? */)
{/* ? */}
// similarly other constructors
// other members
// implicit destructor does the right thing
};