Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- +#include <iostream>
- +using std::cout;
- +using std::endl;
- +
- +class bad_weak_ptr : public std::exception {};
- +
- +template <typename T>
- +struct DefaultDeletePolicy {
- + static void freeMemory(T * pointer) {
- + delete pointer;
- + }
- +};
- +
- +template <typename T>
- +struct ArrayDeletePolicy {
- + static void freeMemory(T * pointer) {
- + delete [] pointer;
- + }
- +};
- +
- +template<typename T, typename DeletePolicy = DefaultDeletePolicy<T> >
- +class weak_ptr;
- +
- +template<typename T>
- +struct Pointer {
- + T * pointer;
- + size_t refCount;
- + size_t weakRefCount;
- + explicit Pointer(T * pointer)
- + : pointer(pointer), refCount(1), weakRefCount(0) {}
- +};
- +
- +
- +template <typename T, typename DeletePolicy = DefaultDeletePolicy<T> >
- +class shared_ptr {
- +
- + friend class weak_ptr<T>;
- +
- +private:
- +
- + Pointer<T> * objPointer;
- +
- + void decrementRefCount() {
- + if (objPointer) {
- + Pointer<T> & object = *objPointer;
- + --object.refCount;
- + if (object.refCount == 0) {
- + DeletePolicy::freeMemory(object.pointer);
- + if (object.weakRefCount == 0) {
- + delete objPointer;
- + }
- + }
- + }
- + }
- +
- + void incrementRefCount() {
- + if (objPointer) {
- + ++objPointer->refCount;
- + }
- + }
- +
- + void assignPointer(T * pointer) {
- + if (pointer) {
- + objPointer = new Pointer<T>(pointer);
- + } else {
- + objPointer = NULL;
- + }
- + }
- +
- +public:
- +
- + shared_ptr(T * pointer = NULL) {
- + assignPointer(pointer);
- + }
- +
- + shared_ptr(const shared_ptr<T> & sharedPointer) {
- + objPointer = sharedPointer.objPointer;
- + incrementRefCount();
- + }
- +
- + shared_ptr(const weak_ptr<T> & weakPointer) {
- + objPointer = weakPointer.objPointer;
- + if (objPointer && objPointer -> refCount == 0) {
- + throw bad_weak_ptr();
- + }
- + incrementRefCount();
- + }
- +
- + T & operator* () const {
- + return *(objPointer->pointer);
- + }
- +
- + T * operator-> () const {
- + return objPointer->pointer;
- + }
- +
- + T & operator[] (int index) {
- + return *(objPointer->pointer + index);
- + }
- +
- + shared_ptr<T> & operator= (T * pointer) {
- + decrementRefCount();
- + assignPointer(pointer);
- + return *this;
- + }
- +
- + shared_ptr<T> & operator= (const shared_ptr<T> & sharedPointer) {
- + if (this != &pointer) {
- + decrementRefCount();
- + objPointer = pointer.objPointer;
- + incrementRefCount();
- + }
- + return *this;
- + }
- +
- + bool operator== (const shared_ptr<T> & sharedPointer) const {
- + return objPointer == sharedPointer.objPointer;
- + }
- +
- + bool operator!= (const shared_ptr<T> & sharedPointer) const {
- + return !(*this == sharedPointer);
- + }
- +
- + operator bool () const {
- + return objPointer && objPointer->pointer;
- + }
- +
- + ~shared_ptr() {
- + decrementRefCount();
- + }
- +
- + int use_count() const {
- + if (objPointer && objPointer->pointer) {
- + return objPointer->refCount;
- + }
- + return 0;
- + }
- +
- + void reset(T * pointer = 0) {
- + decrementRefCount();
- + assignPointer(pointer);
- + }
- +
- + void swap(shared_ptr<T> & sharedPointer) {
- + std::swap(objPointer, sharedPointer.objPointer);
- + }
- +
- +};
- +
- +template<typename T, typename DeletePolicy>
- +class weak_ptr {
- +
- + friend class shared_ptr<T>;
- +
- +private:
- + Pointer<T> * objPointer;
- +
- + void incrementWeakRefCount() {
- + if (objPointer) {
- + ++(objPointer->weakRefCount);
- + }
- + }
- +
- + void decrementWeakRefCount() {
- + if (objPointer) {
- + Pointer<T> & object = *objPointer;
- + --object.weakRefCount;
- + if (object.refCount == 0 && object.weakRefCount == 0) {
- + delete objPointer;
- + }
- + }
- + }
- +
- +public:
- +
- + weak_ptr() {
- + objPointer = NULL;
- + }
- +
- + weak_ptr(const weak_ptr<T> & weakPointer) {
- + objPointer = weakPointer.objPointer;
- + incrementWeakRefCount();
- + }
- +
- + weak_ptr(const shared_ptr<T> & sharedPointer) {
- + objPointer = sharedPointer.objPointer;
- + incrementWeakRefCount();
- + }
- +
- + ~weak_ptr() {
- + decrementWeakRefCount();
- + }
- +
- + int use_count() const {
- + if (objPointer) {
- + return objPointer->refCount;
- + } else {
- + return 0;
- + }
- + }
- +
- + bool expired() const {
- + return (use_count() == 0);
- + }
- +
- + shared_ptr<T> lock() const {
- + if (objPointer->refCount == 0) {
- + return shared_ptr<T>();
- + } else {
- + return shared_ptr<T>(*this);
- + }
- + }
- +
- + weak_ptr<T> & operator= (const weak_ptr<T> & weakPointer) {
- + if (this != &weakPointer) {
- + decrementWeakRefCount();
- + objPointer = weakPointer.objPointer;
- + incrementWeakRefCount();
- + }
- + return *this;
- + }
- +
- + weak_ptr<T> & operator= (const shared_ptr<T> & sharedPointer) {
- + decrementWeakRefCount();
- + objPointer = sharedPointer.objPointer;
- + incrementWeakRefCount();
- + return *this;
- + }
- +
- + void reset() {
- + decrementWeakRefCount();
- + objPointer = NULL;
- + }
- +
- + void swap(weak_ptr<T> & weakPointer) {
- + std::swap(objPointer, weakPointer.objPointer);
- + }
- +
- +};
- +
- +struct MyStruct {
- + void sayHello() {
- + cout << "Hello, world!" << endl;
- + }
- +};
- +
- +template<typename T>
- +void test(shared_ptr<T> sharedPointer) {
- + cout << sharedPointer.use_count() << endl;
- +}
- +
- +weak_ptr<int> weakPointer;
- +
- +void weakTest() {
- + cout << "use count: " << weakPointer.use_count() << endl;
- + shared_ptr<int> shared = weakPointer.lock();
- + if (shared) {
- + cout << *shared << endl;
- + } else {
- + cout << "Expired!\n";
- + }
- +}
- +
- +int main() {
- + shared_ptr<int> intPtr = new int (3);
- + shared_ptr<int> intPtrCopy = intPtr;
- + cout << *intPtrCopy << endl;
- + *intPtr = 10;
- + cout << *intPtrCopy << endl << endl;
- + shared_ptr<int, ArrayDeletePolicy<int> > arrayPtr(new int [10]);
- + for (int i = 0; i < 10; ++i) {
- + arrayPtr[i] = i;
- + }
- + cout << arrayPtr[3] << " " << arrayPtr[5] << endl << endl;
- + cout << (bool)arrayPtr << " " << bool(shared_ptr<int>()) << endl;
- + cout << (intPtr == intPtrCopy) << " " << (intPtr != intPtrCopy) << endl << endl;
- +
- + shared_ptr<MyStruct> myPointer(new MyStruct);
- + myPointer -> sayHello();
- +
- + cout << intPtrCopy.use_count() << endl;
- + test(intPtrCopy);
- + cout << intPtrCopy.use_count() << endl;
- + intPtr.reset();
- + cout << intPtrCopy.use_count() << endl << endl;
- +
- + {
- + shared_ptr<int> sharedPointer = new int(42);
- + weakPointer = sharedPointer;
- + weakTest();
- + }
- + weakTest();
- +
- + shared_ptr<int> a, b;
- + a = new int (20);
- + b = new int (10);
- + cout << "\nBefore swap: " << *a << " " << *b << endl;
- + a.swap(b);
- + cout << " After swap: " << *a << " " << *b << endl;
- +
- + return 0;
- +}
Advertisement
Add Comment
Please, Sign In to add comment