Гибкий член массива в классе с полиморфизмом - PullRequest
1 голос
/ 12 апреля 2020

В C99 вы можете иметь что-то вроде

struct foo
{
    int a;
    int data[];
}; 

И затем выделить с помощью foo* f=(foo*)malloc(sizeof(foo)+n), чтобы получить структуру, в которой длина массива равна n.

Можно ли сделать что-то похожее в C ++, когда класс является подклассом с виртуальными функциями?

Если foo является подклассом bar, тогда выполните что-то вроде std::unique_ptr<bar> f= std::unique_ptr<foo>((foo*)malloc(sizeof(foo)+n))

Я знаю, что этот код не ' работа по освобождению памяти будет выполнена с delete, а выделение - с malloc

Ответы [ 2 ]

0 голосов
/ 12 апреля 2020

Массивы переменной длины на самом деле не являются частью стандарта C ++, а скорее расширением компилятора. Однако, если вы действительно хотите их использовать, я имею в виду, выделяя объект с malloc, вам нужно будет использовать размещение новых для вызова конструктора и вручную вызвать деструктор (который должен быть виртуальным) как f->~bar() перед звонком free. Поскольку malloc создает указатель на память необходимого размера для инициализации объекта, это не должно приводить к неопределенному поведению.

0 голосов
/ 12 апреля 2020

Нет, по стандартным правилам это невозможно. Массивы переменной длины и гибкие члены массива, такие как вы показываете в своем примере, вообще не разрешены в C ++. Также нет эквивалента или альтернативы.

Кроме того, malloc вообще не может использоваться для создания объектов в C ++. Только new с указанным ему правильным типом может динамически создавать объект этого типа. Все остальное недопустимо и вызывает неопределенное поведение, если вы притворяетесь, что объект данного типа был создан.

Начиная с C ++ 20, существуют некоторые исключения из правила выше для определенных типов объектов, которые могут быть созданы неявно, но тем не менее, размер объекта во время компиляции фиксирован по типу и не может изменяться вообще.

Перераспределение для объекта никогда не приводит к тому, что дополнительное хранилище становится частью объекта и никто не может получить к нему доступ, как если бы он был.

...