优先顺序:智能指针和 Class 析构函数
Order of Precedence: Smart Pointer and Class Destructor
假设我们有一个带有智能指针的class。此 class 初始化智能指针所依赖的子系统:类似地,此 class 在销毁时关闭子系统。
如果智能指针依赖于所述子系统来释放其内存,那么如果析构函数首先关闭子系统,就会出现问题。
class FontManager {
public:
FontManager() {
if(TTF_Init() < 0) {
printf( "SDL_ttf could not init! SDL_ttf Error: %s\n", TTF_GetError() );
return;
}
}
~FontManager() {
TTF_Quit();
}
std::unique_ptr<TTF_Font> font;
void operator()(TTF_Font* font) const { TTF_CloseFont(font); }
};
如果我使用原始指针,析构函数将如下所示。
~FontManager() {
// font is raw pointer
TTF_CloseFont(font);
TTF_Quit();
}
那么,首先调用的是指针的析构函数还是 class 的析构函数?
正如子对象是在 class 的构造函数的 开头 构造的(在成员初始化列表中,可能是隐含的),它们是 destroyed at the end 的析构函数(与往常一样,按照相反的构造顺序)。
你当然可以在你的析构函数中reset
你的指针手动;他们仍然会在结束时被摧毁,但没有任何效果。但是 real answer 是将子系统(初始化)封装为它的 自己的资源 ,添加一个新 class 的实例作为 earlier 成员,然后让包含 class 的成员使用 隐式析构函数 。这还有一个额外的好处,即当您使用它来分配智能指针的对象时,可以保证子系统 已初始化 。
假设我们有一个带有智能指针的class。此 class 初始化智能指针所依赖的子系统:类似地,此 class 在销毁时关闭子系统。
如果智能指针依赖于所述子系统来释放其内存,那么如果析构函数首先关闭子系统,就会出现问题。
class FontManager {
public:
FontManager() {
if(TTF_Init() < 0) {
printf( "SDL_ttf could not init! SDL_ttf Error: %s\n", TTF_GetError() );
return;
}
}
~FontManager() {
TTF_Quit();
}
std::unique_ptr<TTF_Font> font;
void operator()(TTF_Font* font) const { TTF_CloseFont(font); }
};
如果我使用原始指针,析构函数将如下所示。
~FontManager() {
// font is raw pointer
TTF_CloseFont(font);
TTF_Quit();
}
那么,首先调用的是指针的析构函数还是 class 的析构函数?
正如子对象是在 class 的构造函数的 开头 构造的(在成员初始化列表中,可能是隐含的),它们是 destroyed at the end 的析构函数(与往常一样,按照相反的构造顺序)。
你当然可以在你的析构函数中reset
你的指针手动;他们仍然会在结束时被摧毁,但没有任何效果。但是 real answer 是将子系统(初始化)封装为它的 自己的资源 ,添加一个新 class 的实例作为 earlier 成员,然后让包含 class 的成员使用 隐式析构函数 。这还有一个额外的好处,即当您使用它来分配智能指针的对象时,可以保证子系统 已初始化 。