Meli jsme napsat sablonu tridy shared_ptr, ktera se chova jako jediny vlastnik nejakeho objektu. To znamena, ze ukazuje na nejakou polozku a pri sve destrukci s sebou vezme i ji. Cele to melo byt navrhnute pomoci Counted-pointers, bylo tedy mozne, aby se vlastnik zduplikoval (treba nekolikrat), a prislusna data mela tedy byt odalokovana az v momente, kdy zahyne posledni vlastnik. Cele to melo byt tak nejak exception-safe.
Melo to mit nasledujici hlavicku:
Kód: Vybrat vše
template <class T> class shared_ptr {
public:
shared_ptr();
explicit shared_ptr(T * p);
~shared_ptr();
shared_ptr& operator= (const shared_ptr & r);
void swap(shared_ptr& r);
void reset(); // "vzda" se vlastnictvi objektu, ale zustava nazivu
T* get() const;
T& operator*() const;
T* operator->() const;
long use_count() const; // pocet vlastniku objektu
bool operator==(const shared_ptr& r); // porovnava, zda ukazuji na stejny objekt
bool operator!=(const shared_ptr& r);
};
Kód: Vybrat vše
#include <stdexcept>
#include <iostream>
#include <string>
template <class T> struct shared_ptr_body {
int count;
T * data;
};
template <class T> class shared_ptr {
private:
shared_ptr_body<T> *body;
public:
shared_ptr() : body(new shared_ptr_body<T>) {
body->count = 0;
body->data = 0;
};
explicit shared_ptr(T * p) : body(new shared_ptr_body<T>) {
body->count = 1;
body->data = p;
};
~shared_ptr() {
if (body->data) {
--body->count;
if (!body->count) {
delete body->data;
delete body;
}
} else {
delete body;
};
};
shared_ptr(const shared_ptr & r) {
body = r.body;
++body->count;
};
shared_ptr& operator= (const shared_ptr & r) {
shared_ptr tmp(r).swap(* this);
return * this;
};
void swap(shared_ptr& r) {
shared_ptr_body<T> *tmp(body);
body = r.body;
r.body = tmp;
};
void reset() {
shared_ptr tmp.swap(* this);
};
T* get() const {
if (body->data)
return body->data;
else
return 0;
};
T& operator*() const {
if (body->data)
return *(body->data);
else
throw std::bad_alloc();
};
T* operator->() const {
return get();
};
long use_count() const {
return body->count;
};
bool operator==(const shared_ptr& r) {
return body->data == r.body->data;
};
bool operator!=(const shared_ptr& r) {
return body->data != r.body->data;
};
};
using namespace std;
int main(int argc, char **argv) {
// pokusy s charem
char *ta = new char('a');
char *tc = new char('c');
shared_ptr<char> a;
a = shared_ptr<char>(ta);
shared_ptr<char> b(a);
shared_ptr<char> c(tc);
cout << *a;
cout << *b;
cout << *c << endl;
c = a;
cout << *a << *b << *c << a.use_count() << ' ' << (a == b) << ' ' << (a != b) << endl;
// pokusy se stringem
string *ts = new string("retezec");
shared_ptr<string> s(ts);
cout << *ts << ": " << ts->size() << endl;
shared_ptr<string> t(s);
s.reset();
t.swap(s);
t = s;
cout << *s << endl;
cout << *t << endl;
};