Я использовал std::vector
много, и недавно я задал мне этот вопрос: "Как std::vector
реализованный?"
У меня было две альтернативы:
1) Связанный список и затем то, чтобы заставлять API чувствовать себя подобно произвольному доступу (т.е. перегрузка operator[]
).
2) Используя new
, например. Foo* temp = new Foo[20]
: Я полагаю, что они делают что-то вроде этого, но затем это поднимает еще один вопрос. Они всегда выделяют максимум (uint32_t
) устройство хранения данных для предоставления произвольного доступа? (Это неэффективно с точки зрения памяти.)
Или есть ли что-то еще, о чем я должен знать?
С помощью svgweb можно встроить произвольный кросс-браузер SVG и изменить его обычными методами DOM. Сюда входит присоединение прослушивателей событий к любой части SVG.
svgweb главная страница:
http://code.google.com/p/svgweb/
svgweb quickstart (также обсуждается добавление прослушивателей событий):
http://codinginparadise.org/projects/svgweb/docs/QuickStart.html
Даже если вы не можете поместить его в традиционный якорь тэга этом пути (я не пытался, это может сработать), вы, по крайней мере, сможете обрабатывать события щелчков и ориентироваться на них, что на самом деле вы после.
-121--3140653-Я думаю, что в этой идее есть некоторые достоинства. Уже есть приложения, которые измеряют скорость ветра с помощью микрофона iPhone, и они, видимо, довольно точны.
Вы также можете включить в эту программу функции распознавания лиц и анализа выражений человека, чтобы включить оценку воздействия на окружающую среду по всем показателям.
В будущем выпуске вы можете измерить скорость и ускорение, с которыми другие пользователи iPhone отходят от события, чтобы определить эффективный радиус и силу взрыва.
Изменить:
Поскольку это проект, я думаю, что многие люди могли бы отстать, я сделал немного больше копания вокруг. Существует исходный код , доступный для приложения iPhone под названием aurioTouch , который, кажется, имеет большую часть того, что вы хотите.
> The code uses: the AU Remote IO audio
> unit to get the audio input and copy
> it to the output the UI presents:
> - Oscilloscope view of the audio
> - time domain
> - frequency domain
> - Scrolling sonogram of the audio
Есть некоторые дополнительные сведения о StackOverflow, связанные с тем, чтобы получить эту работу здесь:
aurioTouch Образец приложения аудио воспроизведение/через не работает? AurioTouch & FFT для тюнера приборов
Удачи, и может ветер быть у вас сзади!
-121--1067439-Он реализован с использованием базового массива.
Невозможно реализовать std:: vector < T >
со связанным списком, поскольку стандарт гарантирует, что элементы списка будут храниться в непрерывной памяти.
Там нет фактического массива вообще в любой приличной реализации (если есть, вы не можете использовать любой объект в нем без конструктора по умолчанию), но просто необработанная память, которая выделяется. Он выделяется таким образом, чтобы они обычно вдоль удвоения каждый раз, когда вам нужно расширить его.
Затем вектор использует в разделе «Распределение», чтобы вызвать конструкторов класса в правильном месте после того, как каждый слот на самом деле используется фактически используемый.
Когда есть расширение, он попытается перераспределить на месте (но это немного глупо и нормально не работает, думают, что уплотнение кучи Windows 98), но обычно в конечном итоге в конечном итоге будет создавать совершенно новое распределение и копирование.
Стандартный вектор STL всегда все вместе, но не все реализации работают так (я знаю, написав некоторые из них). Вероятно, никто не имел бы не именно связанный список.
Педагогическая (и, таким образом упрощенная) версия контейнера под названием «VEC» обсуждается в главе 11 замечательной (вводной) книги «Ускоренного C ++». То, что они описывают, это улавшаяся версия STD :: Vector, но я думаю, что все еще стоит отметить, что:
1) они реализуют свой класс шаблона с точки зрения массива,
2) обсуждают Push_back в Условия трюка (упомянутые выше) выделения большего количества хранения, чем требуются и возвращаются к большему количеству при запуске, а
3) они используют распределитель
Я повторяю, хотя это не означает, что фактические реализации существуют это просто. Но поскольку «ускоренные C ++» довольно широко распространены, тех, кто заинтересован может найти в соответствующей главе одностороннее, что векторные объекты могут быть созданы, скопированы, назначены и уничтожены.
Отредактируйте: в соответствующем примечании я только что нашел следующее сообщение в блоге травой Satter, в котором он комментирует более раннее сообщение в блоге Эндрю Кениг, относительно того, следует ли беспокоиться о векторных элементах, которые являются смежными в памяти: Крыть не: векторы гарантированно могут быть смежными .
Раздел 23.2.4, ¶1 стандарта требует, чтобы арифметика по указателям в вектор работать так же, как и с указателями в массив.
Элементы вектора хранятся непрерывно, что означает, что если V это Вектор, где т это некоторые Тип, кроме BoOL, то он подчиняется Идентичность и V [N] == & V [0] + N для Все 0 <= n
Это гарантирует, что хранение находится в массиве. Конечно, если вы измените размер массива, чтобы быть больше, это может быть перемещено в память.
Я считаю, что STL использует опцию № 2 (или что-то подобное), потому что STD :: Vector <> гарантированно хранит элементы в смежной памяти.
Если вы ищете структуру памяти, которая не должна использовать непрерывную память, посмотрите на STD :: DECE.
Они используют динамически выделенный массив, который восстанавливается по мере необходимости. Необходимо использовать что-то вроде массива, чтобы элементы были смежными в памяти, что гарантируется стандартом.
Кстати, один общий способ экологизации массива - это удвоить размер по мере необходимости. Это так, чтобы если вы вставляете N
элементов o (log n) o (log n)
, выполняются и не более o (n)
пространство впустую.
Вы можете прочитать одну реализацию для себя в SGI (где был первоначально задуман STL).
Нет ни одного способа его реализации. Различные реализации могут быть разными, при условии сохранения семантики и соответствия требованиям.
В любой момент времени должен существовать примитивный массив Т, удовлетворяющий требованиям непрерывности. Однако, как он распределяется, растет, уменьшается и освобождается, зависит от реализации.
Реализацию можно прочитать самостоятельно, она находится прямо там, в заголовочном файле.
Могу сказать, что no реализации используют связанные списки. Они не соответствуют требованиям стандарта.
Из того, что я прочитал в книгах и из функциональности резерва и требований о том, что элементы векторов могут быть смежными, это то, что я думаю, может быть возможным способом реализации вектора.
1) Элементы векторов могут быть смежными, поддерживающими O (1) Случайный доступ и векторы должны быть совместимы с помощью Crays C. Это просто подразумевает, что нет связанных списков.
2) Когда вы называете резерв, он резервирует дополнительную память. Но резерв называет
new T[newSize]
, чтобы зарезервировать больше памяти. В противном случае он будет звонить конструктору по умолчанию. Как объяснил uncleben всякий раз, когда Reserve называется вектором класса, просто выделяет более неинициализированную память USIN его распределитель (если требуется) и скопируйте создание новых объектов в эту память, используя размещение New (если выделено больше памяти)
3) Изначально вектор имеет некоторые емкость по умолчанию. Для чего выделяется неинициализированная память, когда конструкция векторного объекта
4) Push_Back Copy Создает объект в первое доступное местоположение. При необходимости больше памяти необходимо выделить аналогичным образом как резерв
Я считаю, что это третий вариант. Он не может просто использовать new T [n]
, потому что тогда ему фактически придется создавать столько объектов, сколько он выделяет. Например,
std::vector<Foo> v;
v.reserve(10);
Если ваша реализация просто завершила выполнение new Foo [10]
, то вы бы просто построили 10 экземпляров Foo.
Вместо этого он использует свой распределитель для выделения и освобождения необработанной памяти (без создания объектов) и по мере необходимости (например, когда вы на самом деле push_back
объекты) помещает созданные копии экземпляры в правильные места в своей памяти. зарезервировать, используя размещение new , и удаляет их с помощью явных вызовов деструктора (что вы можете делать только в сочетании с размещением new). Класс распределителя предоставляет следующие методы для того, что, как я полагаю, использует реализации векторов
void construct(pointer p, const_reference val);
Returns:
new((void *)p) T(val)
void destroy(pointer p);
Returns:
((T*)p)->~T()
(«Возвращает», вероятно, следует читать «эффект» или что-то подобное.)
Подробнее о размещении new