Как создать массив C-стиля, не называя конструкторов по умолчанию?

Я пишу управляющий памятью шаблонный класс, в котором я хочу создать массив C-стиля фиксированного размера, служить "кучей". Я сохраняю объекты сохраненными в массиве как это:

T v[SIZE];

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

Я думал о решении определить "кучу" как это:

char v[SIZE * sizeof(T)];

... но это даст мне проблемы выравнивания.

Там какой-либо лучший путь состоит в том, чтобы достигнуть этого?

ADD: Поскольку у меня есть специальные требования времени выполнения, важно, чтобы этот класс не делал никаких выделений на глобальной "куче".

ADD 2: РАЗМЕР является аргументом шаблона и известный во время компиляции.

5
задан Johan Kotlinski 16 February 2010 в 16:33
поделиться

6 ответов

Стандартные контейнеры используют распределители для разделения выделения / освобождения от создания / уничтожения. Стандартная библиотека предоставляет единственный распределитель, который размещается в куче.

Этот код объявляет массив, достаточно большой для хранения SIZE элементов типа T с правильным выравниванием:

typedef typename std::tr1::aligned_storage<sizeof(T),std::tr1::alignment_of<T>::value>::type aligned_storage;
aligned_storage array[SIZE];

Решение, использующее std :: allocator не может использоваться для объявления массива в стеке, а поскольку стандартные контейнеры требуют, чтобы пользовательские распределители не содержали состояния, пользовательский распределитель также не может переноситься для выделения в стеке.

Если ваш компилятор не поддерживает std :: tr1 :: alignment_of , вы можете вместо этого использовать boost :: alignment_of .

6
ответ дан 14 December 2019 в 04:37
поделиться

Удивительное время OMG! Сегодня была замечательная статья о хакерских новостях: http ://www.barelyfitz.com/screencast/html-training/css/positioning/

Это в основном показывает вам различные типы позиционирования: относительное, абсолютное, плавающее и т.д., а также почему их использовать. Не забудьте позицию: исправлено хорошо для чего-то вроде легенды, всегда появляющейся на странице.

Я знаю позицию: абсолютный не хорошо, но я не могу объяснить хорошо или привести какие-либо примеры.

Это не то, что это не хорошо. Так и есть. Просто это не правильное решение всех проблем. Точно так же, как молоток не является хорошим решением для ввинчивания в лампочку, но это не указывает молоток как плохой инструмент. (надеюсь, аналогия поможет)

-121--2188201-

Второй абзац Лусеро - правильный подход. Тренер и менеджер - это не люди, это роли, которые играют люди. Теоретически, один и тот же человек может быть, по идее, в качестве StartPlayer, StartCaptain, Coach, Manager и WaterBoy!

Так что вам нужна композиция, а не наследование. Например:

SportsClub myClub = new SportsClub();
Person Bill = new Person();
myClub.Manager = new Manager(Bill);
myClub.Coach = new Coach(Bill);
-121--3832380-

Для обработки проблемы выравнивания можно использовать структуру.

struct Tbuffer { char data_[ sizeof( T ) ]; }

struct Tbuffer heap[ SIZE ];
0
ответ дан 14 December 2019 в 04:37
поделиться

После дальнейшего изучения я нашел ответ

Как UTF-8 работать в Java webapps? .

Все дело в установке URIEncoding = «UTF-8» в разъем tomcat.

Теперь, чтобы выяснить, как это сделать в CMS, мы используем (CQ5/день).

-121--1918453-

Короче говоря, нет, это невозможно сделать со стандартным SQL ANSI.

У вас есть три варианта:

1) Сделайте это в двух запросах - обновление, затем выберите

2) Создайте хранимую процедуру, которая выполнит обновление, а затем вернет select

3) Используйте специфичное для БД расширение, такое как предложение PostgreSQL RETURNING

Обратите внимание, что параметры 2) и 3) являются специфичными для базы данных.

-121--5044365-

Странно, но должно сработать:

long long v[size * sizeof(T)/sizeof(long long)+1];

Этот буфер будет объединен с 64 битами. Но лучше будет выделить память на новый .

В любом случае, если size является переменным - compiller будет динамически распределять память через malloc/new (а не в стеке).

EDIT: Нельзя использовать std:: auto _ ptr для автоматического освобождения буфера. Вместо этого можно использовать scoped _ arr от boost

0
ответ дан 14 December 2019 в 04:37
поделиться

То, что вы ищете, называется распределителем . Хороший обзор можно найти здесь: http://www.codeproject.com/KB/cpp/allocator.aspx

2
ответ дан 14 December 2019 в 04:37
поделиться

Я бы, вероятно, создал массив символов (примерно как вы уже подумали), но выделил бы достаточно места для одного объекта больше, чем вы очень нужно. Затем вам нужно будет написать немного кода, чтобы найти правильное выравнивание для ваших объектов в этом пространстве.

Самым большим требованием к выравниванию для объекта является его собственный размер (в противном случае массивы этих объектов не могли бы быть смежными, что является обязательным). Следовательно, вы выбираете первый адрес в буфере символов, кратный sizeof (T), и начинаете свой массив оттуда.

0
ответ дан 14 December 2019 в 04:37
поделиться

Как я, наверное, это сделаю (посмотрев на реализацию EASTL fixed_vector):

PRAGMA_PRE_ALIGN(sizeof(T)) char[SIZE * sizeof(T)]; PRAGMA_POST_ALIGN(sizeof(T))

...и реализовать специфичные для компилятора макросы PRAGMA_PRE_ALIGN и PRAGMA_POST_ALIGN, которые вставляют правильные #прагмы.

К сожалению, boost и tr1 невозможны для этого проекта.

0
ответ дан 14 December 2019 в 04:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: