Полагаю, это для удобства разработчиков.Это позволяет им определять расширенные type_info
классы и удалять их через указатели на type_info
при выходе из программы, без необходимости встраивать специальную магию компилятора для вызова правильного деструктора или иным образом перепрыгивать через обручи.
несомненно, что реализация может объявить ее виртуальной, поскольку она не меняет набор разрешенных операций над type_info, поэтому переносимая программа не сможет заметить разницу.
Я не знаюне думаю, что это правда.Рассмотрим следующее:
#include <typeinfo>
struct A {
int x;
};
struct B {
int x;
};
int main() {
const A *a1 = dynamic_cast<const A*>(&typeid(int));
B b;
const A *a2 = dynamic_cast<const A*>(&b);
}
Независимо от того, является ли это разумным или нет, первое динамическое приведение разрешено (и оценивается как нулевой указатель), тогда как второе динамическое приведение не разрешено.Таким образом, если в стандарте было определено type_info
, чтобы иметь не виртуальный деструктор по умолчанию, но реализация добавила виртуальный деструктор, то переносимая программа могла бы отличить [*].
Мне кажется, прощепоместить виртуальный деструктор в стандарт, а затем:
a) добавить в стандарт примечание, что, хотя определение класса подразумевает, что type_info
не имеет виртуальных функций, разрешено иметь виртуальныйдеструктор.
б) определить набор программ, которые могут различать, является ли type_info
полиморфным или нет, и запретить их все.Они могут быть не очень полезными или продуктивными программами, я не знаю, но чтобы запретить их, вы должны придумать какой-то стандартный язык, который описывает конкретное исключение, которое вы делаете из обычных правил.
ПоэтомуЯ думаю, что стандарт должен либо обязать виртуального деструктора, либо запретить его.Сделать его необязательным слишком сложно (или, может быть, я должен сказать, что я думаю, что это будет считаться излишне сложным. Сложность никогда не остановила комитет по стандартам в тех областях, где это считалось стоящим ...)
Если бы его запретили,хотя, тогда реализация могла бы:
- добавить виртуальный деструктор к некоторому производному классу
type_info
- и получить все его объекты typeinfo из этого class
- использовать это внутренне как полиморфный базовый класс для всего
, что решило бы ситуацию, которую я описал вверху поста, , но статический типВыражение typeid
все равно будет const std::type_info
, поэтому реализациям будет сложно определить расширения, в которых программы могут dynamic_cast
достигать различных целей, чтобы увидеть, какой тип объекта type_info
они имеют в конкретном случае.Возможно, стандарт надеялся разрешить это, хотя реализация всегда могла предложить вариант typeid
с другим статическим типом или гарантировать, что static_cast
для определенного класса расширения будет работать, и затем позволить программе dynamic_cast
изтам.
Итак, насколько я знаю, виртуальный деструктор потенциально полезен для разработчиков, и его удаление не принесет ничего другого, кроме того, что мы не будем тратить время на размышления о том, почему он существует;)
[*] На самом деле, я этого не демонстрировал.Я продемонстрировал, что нелегальная программа при прочих равных компилируется.Но реализация может возможно обойти это, гарантируя, что все не равны, и что это не компилируется.is_polymorphic
в Boost не является переносимым, поэтому, хотя программа и может проверить, что класс является полиморфным, у соответствующей программы не может быть способа проверить, что класс не полиморфный, это не должно быть.Хотя я думаю, что даже если это невозможно, доказать, что для удаления одной строки из стандарта, достаточно много усилий.