Безопасно ли использовать CRTP для деструктора? - PullRequest
0 голосов
/ 26 апреля 2018

CRTP может вызывать метод дочернего класса, например, виртуальную функцию, хотя виртуальная функция разрешается во время выполнения.

Насколько я знаю, вызывать виртуальную функцию в деструкторе небезопасно. То же самое верно для CRTP? Безопасно или небезопасно вызывать дочерний метод с использованием CRTP?

Edit:

Если это небезопасно, как насчет случая множественного наследования? Например,

template<typename T, typename V>
struct CRTP {
    ~CRTP()
    {
        static_cast<V*>(static_cast<T*>(this))->run();
    }
};

struct Run {
    void run() { std::cout << "run" << std::endl; }
};

struct A : Run, CRTP<A, Run> {

};

Здесь порядок уничтожения: A-> CRTP-> Run. Безопасно ли вызывать функции Run в деструкторе CRTP?

1 Ответ

0 голосов
/ 26 апреля 2018

Насколько я знаю, вызывать виртуальную функцию в деструкторе небезопасно. То же самое верно для CRTP? Безопасно или небезопасно вызывать дочерний метод с использованием CRTP?

Это не безопасно. Применяются те же соображения. В конструкторе или деструкторе нет ни одного производного объекта . Поэтому вызов функции-члена, будь то по CRTP или путем мошенничества с виртуальными функциями и косвенное обращение через не виртуальные члены, приводит к неопределенному поведению.

К сожалению, ваш второй пример все еще имеет неопределенное поведение. Вы не можете static_cast<>(this) ни с чем, кроме как с квалификацией cv void или void*, или с базой (которой Run не является).

...