Ефективно използване на STL вектор

Използване на STL контейнер вектор. векторна производителност Използването на C++ стандартни библиотечни контейнери винаги се ръководи от простота и удобство, производителност. Но като всеки "инструмент", той трябва да се използва правилно, защото доброто и ефективно средство в неумели ръце може да бъде безполезно или неефективно. В тази кратка статия ще ви кажа как да го използвате възможно най-ефективно и какви проблеми, клопки могат да възникнат при първата ви среща.

Да започнем от самото начало STL - Standard Template Library. Тоест всичко, което е изразено от шаблона(ите) в стандартната библиотека, е STL. Но в по-голямата си част контейнерите, алгоритмите и итераторите се считат за STL. STL отдавна е включен в стандартната C++ библиотека, но все още не всеки го използва в най-голяма степен, главно поради незнание за съществуването на определени шаблонни класове.

И така ще се върнем конкретно към вектора. Векторният контейнер е същият като масив, който може да съдържа всеки вграден или дефиниран от потребителя тип. Но в сравнение с вградения масив има редица предимства.

- Той знае собствения си размер, (метод size()) - Можете лесно да промените размера (добавяне, премахване на елементи), по време на изпълнение - При премахване, почистване, извиква деструктори на класове (е, това предимство е спорно =))

Нека преминем през основните методи.

    push_back(element) - добавяне на елемент в края на вектора pop_back(element) - изтриване на последния елемент от вектора insert(***) - три опции (презареждане на метода) за вмъкване във всяка област във вектора, първият параметър е позицията на вмъкване, дадена на итераторите, останалите показват контейнера, или количеството и контейнера, или двойка итератори, показващи от кое до коевземете данни от друг контейнер. erase(iterator или iterator from, and to) - премахва елемент или поредица от елементи от вектор. begin() - връща итератор, сочещ към началото на колекцията. end() - връща итератор, сочещ към края на колекцията. В същото време той не сочи към последния елемент, а към имагинерен елемент зад последния at (index) - методът за достъп до елементите на колекцията, за разлика от оператора [], проверява излизането от границите на колекцията и в този случай генерира изключение. clear() - премахва всички елементи от колекцията и ако съдържа обекти от клас, извиква техните деструктори. И ако указателите към обекти, тогава ще имате изтичане на памет (изтичане на памет =)), така че никой няма да извика delete вместо вас.

Време е да го видите в действие!

Когато итерирате върху вектор чрез итератори, трябва да се обучите да пишете pre-increment(++it), така че епо-ефективно.

Създаване на статичен вектор:

Най-честият случай на проблеми при създаването на статичен вектор е създаването му в клас. За да създадете статичен вектор в клас, трябва да го опишете в .h и да го дефинирате в .cpp. В този случай слагам всичко в един файл, само за по-лесно. По този начин можете да създадете не само статичен вектор, но и всеки друг статичен контейнер.

Сега за ефективността

Векторът е ефективен, когато имате нужда от контейнер, в който ще натрупвате елементи. Тоест добавете. Вектор е ефективен, когато се добави към края с push_back() и се премахне от края с pop_back(). При вмъкване или изтриване на произволно място (методи insert() и erase()),ефективността на вектора е по-лошаот list(list) или deque(deque). Това се дължи на факта, че векторът съхранява данни впамет последователно, което дава бърз произволен достъп и възможност за използване на вектора като обикновен масив. Например, в същитеOpenGLфункции, вместо указател към C масив, можете да посочите &vector_name. Векторът има не само size(), но и капацитет(), капацитетът е максималният брой елементи, които, когато бъдат добавени, няма да доведат до преразпределяне на вътрешния буфер. Когато тази стойност бъде превишена, векторът заделя нов вътрешен буфер (разпределител) и копира всички елементи от стария буфер в новия, като същевременно изтрива от стария. Тоест, ако съхраняваме големи обекти от клас в него, тогава тази операция ще бъде доста скъпа. Това ще бъде особено остро при големи обекти със сложен деструктор. Капацитетът се задава от внедряването на самата стандартна библиотека.

Ако, от друга страна, съхранява указатели към обекти във вектора, тогава това значително увеличава ефективността на съхраняването във вектора, особено големи обекти. Съхраняването на неголеми обекти или вградени типове във вектора е доста ефективно.

Заключение Ако не възнамерявате често да изтривате елементи от контейнера и не е необходимо да вмъквате елементи в началото и средата. И вие ще съхранявате не-големи обекти, вградени типове или указатели към всякакви обекти (големи или не толкова =)). По-добре е да предпочетете вектор и да запомните какви операции се извършват с него, какво правят, включително в него. И кой от тях няма да е твърде скъп.