#include <iostream>
template <typename T>
class Stack {
private:
struct StackElem {
T data;
StackElem *next;
};
StackElem *top;
public:
Stack() : top(NULL) {}
~Stack() {
while (!empty())
pop();
}
Stack(Stack const &); /* hf */
Stack & operator=(Stack const &); /* hf */
void push(T const & data) {
StackElem *new_elem = new StackElem;
new_elem->data = data;
new_elem->next = top;
top = new_elem;
}
T pop() {
T top_data = top->data;
StackElem *old_top = top;
top = top->next;
delete old_top;
return top_data;
}
bool empty() const {
return top == NULL;
}
class Iterator {
private:
StackElem *curr;
public:
Iterator() {}
Iterator(StackElem *curr) : curr(curr) {}
Iterator & operator++ () {
curr = curr->next;
return *this;
}
Iterator operator++ (int) {
Iterator old_value = *this;
curr = curr->next;
return old_value; // posztinkremens!
}
T& operator* () {
return curr->data;
}
bool operator== (Iterator const & that) {
return this->curr == that.curr;
}
bool operator!= (Iterator const & that) {
return this->curr != that.curr;
}
};
Iterator begin() {
return Iterator(top);
}
Iterator end() {
return Iterator(NULL);
}
};
int main() {
Stack<char> s;
char c;
while (std::cin >> c)
s.push(c);
std::cout << "Visszafelé a beírt szöveg, ahogy a veremben vannak, iterátorral:";
for (Stack<char>::Iterator it = s.begin(); it != s.end(); ++it)
std::cout << *it;
std::cout << std::endl;
std::cout << "Visszafelé a beírt szöveg, pop() függvénnyel:";
while (!s.empty())
std::cout << s.pop();
std::cout << std::endl;
}
Templatelt tömb, ami azt std::vectort használja a gyors/rövid implementációhoz. Automatikusan átméreteződik, ha túlindexelik. A privát "öröklés" (AMI OOP-ÉRTELEMBEN VÉVE NEM ÖRÖKLÉS, MERT NEM FEJEZ KI "X EGY FAJTA Y" KAPCSOLATOT!!!) elrejti az ősosztály függvényeit, és magát az öröklés tényét. Így nem lesz automatikus Tomb<T>->std::vector<T>
konverzió, nem lehet majd tévesen meghívni a "régi" operator[]
-t, amelyik nem méretez át.
#include <iostream>
#include <vector>
template <typename T>
class Tomb: private std::vector<T> {
private:
/* Nem kell további adattag */
public:
T& operator[](size_t i) {
if (i>=size())
this->resize(i+1);
return std::vector<T>::operator[](i);
}
/* a privát "öröklés" (nem öröklés!) miatt ezek a függvények
* és típusok nem látszanak kívülről. hogy újra láthatóvá
* tegyük őket, arra a using kulcsszó való. */
using std::vector<T>::size;
using std::vector<T>::empty;
using std::vector<T>::iterator;
using std::vector<T>::begin;
using std::vector<T>::end;
};
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
template <typename T>
class myvector {
T* data;
myvector(size_t s) {
data = new T[s];
}
T & operator[] (size_t idx) {
return data[idx];
}
/* copy ctor, etc, ami kell */
};
template <>
class myvector<bool> {
unsigned char * data;
public:
myvector(size_t s) {
data = new unsigned char [(s+7) / 8] ();
}
bool get_bit(size_t idx) const {
return (data[idx/8] >> (idx % 8)) & 1;
}
void set_bit(size_t idx, bool b) {
if (b == true) {
data[idx/8] |= 1 << (idx % 8);
} else {
data[idx/8] &= ~(1 << (idx % 8));
}
}
// Indexeléskor ilyen objektum keletkezik.
// Ennek az értékadó és konverziós operátora van
// úgy overloadolva, hogy aztán bitként viselkedik.
class Proxy {
private:
myvector & v;
size_t idx;
public:
Proxy(myvector & v, size_t idx) : v(v), idx(idx) {}
operator bool () const {
return v.get_bit(idx);
}
Proxy const & operator= (bool b) const {
v.set_bit(idx, b);
return *this;
}
};
Proxy operator[] (size_t idx) {
return Proxy(*this, idx);
}
~myvector() {
delete[] data;
}
// + copy ctor, etc
};
int main() {
myvector<bool> v(200);
v[175] = true; // v.operator[](175) .operator=(true)
std::cout << v[12]; // v.operator[](12) .operator bool()
// miért nem megy? hogy kell javítani?
// v[175] = v[12];
}