#include <iostream>
#include <memory>
#include <string>
using namespace std;
class myException
{
public:
char * errorMsg() { return "Oops."; }
};
template<class T>
class RCSmartPointer
{
public:
RCSmartPointer(T* ptrToRC = 0);
RCSmartPointer(const RCSmartPointer& rhs);
~RCSmartPointer();
RCSmartPointer& operator=(const RCSmartPointer& rhs);
T* operator->() const;
T& operator*() const;
private:
T * pRC;
void initialize();
};
template<class T>
void RCSmartPointer<T>::initialize()
{
if ( pRC == 0 )
return;
if ( pRC->isShareable() == false )
{
pRC = new T(*pRC);
}
pRC->addRef();
}
template<class T>
RCSmartPointer<T>::RCSmartPointer(T* ptrToRC):
pRC(ptrToRC)
{
initialize();
}
template<class T>
RCSmartPointer<T>::RCSmartPointer(const RCSmartPointer& rhs):
pRC(rhs.pRC)
{
initialize();
}
template<class T>
RCSmartPointer<T>::~RCSmartPointer()
{
if ( pRC )
pRC->removeRef();
}
template<class T>
RCSmartPointer<T>& RCSmartPointer<T>::operator=(const RCSmartPointer& rhs)
{
if ( pRC == rhs.pRC )
return *this;
if ( pRC )
pRC->removeRef();
pRC = rhs.pRC;
return *this;
}
template<class T>
T* RCSmartPointer<T>::operator->() const
{
return pRC;
}
template<class T>
T& RCSmartPointer<T>::operator*() const
{
return *pRC;
}
class ReferenceCounted
{
public:
void addRef() { ++referenceCount; }
void removeRef() {
if ( --referenceCount == 0 )
delete this;
}
void markNotShareable() { shareable = false; }
bool isShareable() { return isShareable; }
bool isShared() { return referenceCount > 1; }
protected:
ReferenceCounted():referenceCount(0), shareable(true) {}
ReferenceCounted(const ReferenceCounted& rhs):referenceCount(0), shareable(true) {}
ReferenceCounted& operator=(const ReferenceCounted& rhs) { return *this; }
virtual ~ReferenceCounted(){}
private:
int referenceCount;
bool shareable;
};
class Point
{
public:
Point (int x, int y):myX(x), myY(y) { cout << "Point constructor called"<< endl;}
Point (const Point & rhs):
myX(rhs.myX),
myY(rhs.myY){ cout << "Point copy constructor called" << endl;}
~Point(){ cout << "Point destructor called" << endl;}
int GetX() const { return myX; }
void SetX(int x) { myX = x; }
int GetY() const { return myY; }
void SetY(int y) { myY = y; }
private:
int myX;
int myY;
};
class Rectangle
{
public:
Rectangle( Point upperLeft, Point lowerRight ):
rcRect(new countedRect(upperLeft, lowerRight))
{}
Rectangle( Point * pUpperLeft, Point * pLowerRight ):
rcRect(new countedRect(*pUpperLeft, *pLowerRight))
{}
Rectangle( int upperLeftX, int upperLeftY, int lowerRightX, int lowerRightY ):
rcRect(new countedRect(new Point(upperLeftX,upperLeftY), new Point(lowerRightX,lowerRightY)))
{}
~Rectangle(){ cout << "In Rectangle's destructor" << endl; }
int GetWidth() { return rcRect->myLowerRight->GetX() - rcRect->myUpperLeft->GetX(); }
int GetHeight() { return rcRect->myLowerRight->GetY() - rcRect->myUpperLeft->GetY(); }
void DangerousMethod() { throw myException(); }
private:
struct countedRect : public ReferenceCounted
{
char * cString;
Point * myUpperLeft;
Point * myLowerRight;
countedRect( const Point * ul, const Point * lr) { initialize(ul,lr); }
countedRect( Point ul, Point lr ) { initialize(&ul, &lr); }
countedRect( const countedRect & rhs) { initialize(rhs.myUpperLeft, rhs.myLowerRight); }
~countedRect()
{
delete myUpperLeft;
delete myLowerRight;
}
void initialize(const Point * ul, const Point * lr)
{
myUpperLeft = new Point(*ul);
myLowerRight = new Point(*lr);
}
friend class RCSmartPointer<countedRect>;
};
RCSmartPointer<countedRect> rcRect;
};
int main()
{
try
{
cout << "Begin round 1..." << endl;
Point pUL(0,0);
Point pLR(20,30);
Rectangle myRectangle(pUL, pLR);
int w = myRectangle.GetWidth();
int h = myRectangle.GetHeight();
cout << "the Rectangle is " << w << " by " << h << endl;
myRectangle.DangerousMethod();
cout << "You never get here.\n" << endl;
}
catch ( myException & e )
{
cout << "caught exception: " << e.errorMsg() << "\n\n" << endl;
}
return 0;
}