// File: safe_ref_counted_guard.cpp // Author: Chris Gill cdgill@cse.wustl.edu // Purpose: source file for copy-safe (reference counted) guard smart pointer #include "stdafx.h" #include "safe_ref_counted_guard.h" // default constructor SafeRefCountedGuard::SafeRefCountedGuard () : ptr_ (0) { } // copy constructor SafeRefCountedGuard::SafeRefCountedGuard (const SafeRefCountedGuard &sdrcg) : ptr_(sdrcg.ptr_) { cout << "copy constructing SafeRefCountedGuard that aliases address " << ptr_; if (ptr_) { ++(ptr_->ref_count_); cout << " with value " << *ptr_ << " which now has reference count " << ptr_->ref_count_; } cout << endl; } // destructor SafeRefCountedGuard::~SafeRefCountedGuard () { cout << "Destructing SafeRefCountedGuard that aliases address " << ptr_; if (ptr_) { --(ptr_->ref_count_); cout << " with value " << *ptr_ << endl << " which now has reference count " << ptr_->ref_count_ << endl; if (ptr_->ref_count_ == 0) { delete ptr_; } } else { cout << endl; } } // assignment operator SafeRefCountedGuard & SafeRefCountedGuard::operator= (const SafeRefCountedGuard &sdrcg) { // check for assignment referring to the same scope detector object if (ptr_ != sdrcg.ptr_) { // implies this != & sdrcg (includes the case of self-assignment!) // first, dissociate from any object the guard was pointing to if (ptr_) { --(ptr_->ref_count_); if (ptr_->ref_count_ == 0) { delete ptr_; } } // then, associate with the object that the assigned guard points to ptr_ = sdrcg.ptr_; if (ptr_) { ++(ptr_->ref_count_); } } // return a reference to allow chained assignment operators return *this; } // dereference operator ScopeDetector & SafeRefCountedGuard::operator*() { return *ptr_; } // arrow operator ScopeDetector * SafeRefCountedGuard::operator->() { return ptr_; } // accessor ScopeDetector * SafeRefCountedGuard::ptr() const { return ptr_; } // mutator void SafeRefCountedGuard::ptr(ScopeDetector *sdp) { // if passed pointer is same as it already has, do nothing if (ptr_ != sdp) { // dissociate from the object to which it was pointing if (ptr_) { --(ptr_->ref_count_); if (ptr_->ref_count_ == 0) { delete ptr_; } } // associate with the passed object, if there is one ptr_ = sdp; if (ptr_) { ++(ptr_->ref_count_); } } }