Teskari iteratorlar. Bu iteratorlar konteynerning elementlarini teskari olishni amalga oshiradi. Buning uchun reverse_iterator tipi ishlatiladi. Bu tipdagi iteratorlarga konteynerning elementlarini olish uchun rbegin() i rend() funksiyalaridan foydalaniladi.
#include "stdafx.h" #include #include using namespace std; int main()
{
int myints[] = { 1, 2, 3, 4, 5 };
vector v (myints, myints+ sizeof(myints)/sizeof(myints[0]));
for (vector::reverse_iterator iter = v.rbegin(); iter != v.rend(); ++iter) std::cout << *iter << " | ";
cout << endl; system("pause");
return 0;
}
Agar konteynerni o‘zgartirishdan himoyaya qilish va teskarisi kerak bo‘lsa, const_reverse_iterator tipidagi iteratordan va uning crbegin() va crend() funksiyalaridan foydalanish maqsadga muvofiqdir. Yuqoridagi dasturga quyidagi fragmentni yozish yetarli bo‘ladi.
for (vector::const_reverse_iterator iter = v.crbegin(); iter != v.crend();
++iter)
std::cout << *iter << " | ";
Shuningdek iteratorlari qo‘shima amallarga ham ega (list va forward_list konteynerlaridan tashqari):
iter+n - n ta pozitsiya keyingi elementni ko‘rsatuvchi iteratorni qaytaradi.
iter–n - n ta pozitsiya oldingi elementni ko‘rsatuvchi iteratorni qaytaradi.
iter+=n - iteratorni n - chi pozitsiyaga o‘tkazadi
iter-=n - iteratorni n - chi pozitsiyaga o‘tkazadi
iter1-iter2 - iter1 va iter2 lar orasidagi pozitsiyalar sonini qaytaradi
[>], [>=], [<], [<=] - taqqoslash amallari. Agar iterator oxiriga yaqin elementni ko‘rsatsa boshqasidan katta.
Taqqoslash amallari uchun ko‘chirib o‘tish iteratorlari va bazaviy iteratorlar uchun baʻzi C++ dasturlashda farqlari bor.
5.1-jadval. Taqqoslash amallari yozish uslublari.
Ko‘chirib o‘tish iteratorlari uchun.
Ekvivalent bazaviy iteratorlari uchun.
move_ita == move_itb
basic_ita == basic_itb
move_ita != move_itb
!(basic_ita == basic_itb)
move_ita < move_itb
basic_ita < basic_itb
move_ita <= move_itb
!(basic_itb < basic_ita)
move_ita > move_itb
basic_itb < basic_ita
move_ita >= move_itb
!(basic_ita < basic_itb)
Xotiranitaqsimlovchilarvaulargaqo‘yilgantalablar. Dinamik xotira bilan ishlashda maxsus truklarni, fragmentlardan foydalanish bo‘lmasa, ko‘pigina algoritmlardan foydalanish samarasiz bo‘lshi mumkin. Bunga misol sifatida ikkita holatni ko‘rib chiqamiz. new va delete operatorlarining qayta aniqlanib yuklanishida sintaktik konstruktorlar kichikroq bo‘ladi va dastur lokalizatsiya qilish oddiy bo‘ladi. Shuningdek protsessordagi amallar tizimida ham qayta aniqlash sodir bo‘ladi.
Avvalo, xotirani ishlashini tezlashtirishda aqlli allocator qanchalik foydasi borligini aniqlash lozim. Buning uchun oddiy test misollarini (C++ va S#) tillarida ko‘rib chiqaylik ( bu xotira bilan ishlash uchun yaxshi menejer hisoblanadi va obʻyektlarni avlodlarga ajratadi, turli o‘lchamdagi obʻyektlar uchun turli pullardan (joylar) foydalanadi).
C++ dagi dastur
class Node { public:Node* next;};
// ...
for (int i = 0; i < 10000000; i++) { Node* v = new Node();}
C++ dagi dastur
class Node
{public Node next;}
// ...
for (int l = 0; l < 10000000; l++)
{var v = new Node();}
Dasturlar sharsimon vakum usulini qo‘llab ham vaqt bo‘yicha solishtirilsa 10 barovar (62 ms va 650 ms) farq bo‘lmoqda. Shuningdek C# ishini tugutdi, ammo C++ da esa yaxshigini xotira ajratilan, bu hali o‘chirish kerak.