Хорошо, давайте начнем с самого начала.Идеальный способ вернуть буфер переменной длины:
MyStruct my_func(int a) { MyStruct s; /* magic here */ return s; }
К сожалению, это не работает, так как sizeof (MyStruct) вычисляется во время компиляции.Все, что переменной длины, просто не помещается в буфер, размер которого рассчитывается во время компиляции.Следует отметить, что это происходит с каждой переменной или типом, поддерживаемым c ++, поскольку все они поддерживают sizeof.В C ++ есть только одна вещь, которая может обрабатывать размеры буферов во время выполнения:
MyStruct *ptr = new MyStruct[count];
Так что все, что собирается решить эту проблему, обязательно будет использовать массив новой версии.Это включает в себя std :: vector и другие решения, предложенные ранее.Обратите внимание, что у трюков, таких как размещение новых для массива char, точно такая же проблема с sizeofБуферам переменной длины просто нужны куча и массивы.Нет никакого способа обойти это ограничение, если вы хотите остаться в рамках c ++.Далее требуется более одного объекта!Это важно.Вы не можете сделать объект переменной длины с C ++.Это просто невозможно.
Ближайший к объекту переменной длины, который предоставляет c ++, - это "переход от типа к типу".Каждый объект не обязательно должен быть одного типа, и вы можете во время выполнения манипулировать объектами разных типов.Но каждая часть и каждый завершенный объект все еще поддерживают sizeof, и их размеры определяются во время компиляции.Программисту остается только выбрать, какой тип вы используете.
Итак, каково наше решение проблемы?Как вы создаете объекты переменной длины?std :: string предоставляет ответ.Он должен иметь более одного символа внутри и использовать альтернативу массива для выделения кучи.Но все это обрабатывается stdlib, и программисту не нужно заботиться.Тогда у вас будет класс, который манипулирует этими std :: strings.std :: string может это сделать, потому что на самом деле это две отдельные области памяти.Sizeof (std :: string) возвращает блок памяти, размер которого можно вычислить во время компиляции.Но фактические данные переменной длины находятся в отдельном блоке памяти, выделенном версией массива new.
Версия массива new имеет некоторые собственные ограничения.sizeof(a[0])==sizeof(a[1])
и т. Д. Сначала выделение массива, а затем размещение нового для нескольких объектов разных типов обойдут это ограничение.