Порядок приоритета: умный указатель и деструктор класса - PullRequest
0 голосов
/ 02 ноября 2018

Предположим, у нас есть класс с умным указателем. Этот класс инициализирует подсистему, на которую опирается интеллектуальный указатель: аналогично, этот класс закрывает подсистему при уничтожении.

Если интеллектуальный указатель полагается на указанную подсистему для освобождения своей памяти, то, если деструктор сначала закрывает подсистему, возникает проблема.

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();
}

Итак, что вызывается первым: деструктор указателя или деструктор класса?

1 Ответ

0 голосов
/ 02 ноября 2018

Так же, как подобъекты создаются в начале конструктора класса (в списке инициализатора члена, возможно, неявно), они уничтожаются в конце деструктора (в порядке, обратном их построению, как обычно).

Вы, конечно, можете reset указатели вручную в своем деструкторе; они все равно будут уничтожены, но безрезультатно. Но реальный ответ состоит в том, чтобы инкапсулировать подсистему (инициализацию) как ее собственный ресурс , добавить экземпляр этого нового класса как ранее член, а затем пусть содержащий класс использует неявный деструктор . Это дает дополнительное преимущество, гарантируя, что подсистема инициализируется при использовании ее для выделения объекта интеллектуального указателя.

...