Следуя вопросу, заданному здесь ранее сегодня, и множеству похожих тематических вопросов, я m здесь, чтобы спросить об этой проблеме с точки зрения стандарта.
struct Base
{
int member;
};
struct Derived : Base
{
int another_member;
};
int main()
{
Base* p = new Derived[10]; // (1)
p[1].member = 42; // (2)
delete[] p; // (3)
}
В соответствии со стандартом (1)
имеет правильный формат, потому что Dervied*
(которое является результатом new-expression) может быть неявно преобразовано в Base*
(черновик C++11, §4.10/3):
Значение prvalue типа «указатель на cv D», где D — тип класса, может быть преобразовано в значение prvalue типа «указатель на cv B», где B — это базовый класс (пункт 10) D. Если B является недоступным (пункт 11) или неоднозначным (10.2) базовым классом D, программа, которая требует этого преобразования, является неправильно сформированной. Результатом преобразования является указатель на подобъект базового класса объекта производного класса. Значение нулевого указателя преобразуется в значение нулевого указателя целевого типа.
(3)
приводит к неопределенному поведению из-за §5.3.5/3:
В первом варианте (удалить объект), если статический тип удаляемого объекта отличается от его динамического типа, статический тип должен быть базовым классом динамического типа удаляемого объекта. удален, а статический тип должен иметь виртуальный деструктор, иначе поведение не определено. Во втором варианте (удалить массив), если динамический тип удаляемого объекта отличается от его статического типа, поведение не определено.
Является ли (2)
допустимым в соответствии со стандартом или это приводит к неправильной структуре программы или неопределенному поведению?
изменить: улучшить формулировку
(2)
неправильно сформирован . Я провел последние два часа в поисках чего-то вроде того, что сказал Бо Перссон, то есть(p + n)
использует статический типp
для вычисления смещения, но у меня сложилось впечатление, что абзац, касающийсяoperator+
, не подразумевает этого. - person Vitus   schedule 26.08.2011sizeof(Base) == sizeof(Derived)
, хотя большинство реализаций будут правильными. - person Vitus   schedule 26.08.2011