//
Purpose. Proxy design pattern lab
(reference counting)
//
// Discussion. One of the four common situations in which the Proxy pattern
is
// applicable is as a "smart reference" - a replacement for a
bare pointer that
// performs additional actions when an object is
referenced. Here, that addi-
//
tional action is "reference counting". The original String class becomes
// the inner
"body" class. A
"count" data member is added to the body class.
// A new outer
"handle" class is created that contains a pointer to a body
//
instance. Body instances common to
multiple handle instances are shared by
// simply incrementing the
reference count. As these shared
references go away,
// the reference count is decremented. When the count goes to zero, the body
//
instance is freed. This mechanism
allows the "reference counted class" to
// perform simple-minded
garbage collection on itself.
//
// Assignment.
// o Change the
class String to an inner body StringRep.
// o Add a count_ private data
member to StringRep. Initialize count_
to 1 in
// the default ctor and
the 1-arg ctor.
// o Create a new outer handle class String. Make String a
friend of StringRep.
// o String has one private data member - a pointer
to a StringRep (rep_).
// o The String default ctor initializes rep_ with
'new StringRep("")'.
// o The String 1-arg ctor initializes rep_
with 'new StringRep(arg)'.
// o The String copy ctor initializes rep_ with
the rep_ of the initializing
//
String. It also increments the
count_ of that rep_.
// o The String dtor decrements the count_ of rep_
and deletes rep_ if count_
// is
0.
// o The String operator=(): increments the count_ of the
"rhs" rep_,
//
decrements the count_ of its own rep_ and deletes rep_ if count_ is
0,
// assigns the "rhs"
rep_ to its own rep_, and returns *this.
// o Add cout statements to
String to generate the target output.
// o Make the operator<<()
function a friend of both StringRep and String.
// Modify it as necessary.
#include
<iostream.h>
#include <string.h>
class String
{
public:
friend
ostream& operator << ( ostream&, String& );
String() {
cout << "
String ctor (def):" << endl;
str_ = NULL;
}
String( const char* in
) {
cout << " String ctor: " << in <<
'.' << endl;
str_ = new
char[strlen(in) + 1];
strcpy(
str_, in );
}
String( String& str ) {
cout << " String ctor (copy): " <<
str.str_ << '.' << endl;
str_ = new char[strlen(str.str_) + 1];
strcpy( str_, str.str_ );
}
~String()
{
cout << "
String dtor: " << str_ << '.' << endl;
delete str_;
}
String& operator= ( String& rhs ) {
if (this == &rhs) return *this;
delete str_;
str_ = new char[strlen(rhs.str_) +
1];
strcpy( str_, rhs.str_
);
return *this;
}
private:
char*
str_;
};
ostream& operator << ( ostream&
os, String& str ) { return os << str.str_; }
void main(
void ) {
String a( "hello" );
String
b = "world";
String c( a );
String
d = a;
String e;
a = b;
e = b;
cout << "a is " << a
<< '.' << endl;
cout
<< "b is " << b << '.' << endl;
cout << "c is " << c
<< '.' << endl;
cout
<< "d is " << d << '.' << endl;
cout << "e is " << e
<< '.' << endl;
}
/****** Current output
******/
// String ctor:
hello.
// String ctor:
world.
// String ctor (copy):
hello.
// String ctor (copy):
hello.
// String ctor
(def):
// a is world.
// b is world.
// c is hello.
// d is
hello.
// e is world.
//
String dtor: world.
//
String dtor: hello.
//
String dtor: hello.
//
String dtor: world.
//
String dtor: world.
/****** Target output ******/
// StringRep ctor: hello.
// String
ctor: hello.
// StringRep ctor:
world.
// String ctor: world.
// String ctor (copy): hello.
//
String ctor (copy): hello.
//
StringRep ctor: .
// String ctor (def):
// StringRep dtor: .
// a is
world.
// b is world.
// c is hello.
// d is hello.
// e is
world.
// String dtor: world, before decrement, count is 3
// String
dtor: hello, before decrement, count is 2
// String dtor: hello, before
decrement, count is 1
//
StringRep dtor: hello.
// String dtor: world, before decrement,
count is 2
// String dtor: world, before decrement, count is 1
// StringRep dtor: world.