• Welcome to Computer Association of SIUE - Forums.
 

Smart Pointers

Started by William Grim, 2007-09-08T19:46:40-05:00 (Saturday)

Previous topic - Next topic

William Grim

Smart pointers are a special case of the Proxy Pattern, and they adhere to the principles of Resource Acquisition is Initialization.  The purpose of the smart pointers is both to prevent unintended memory leaks and, in the case of the example shown below, to prevent unauthorized access to a class' internal data while making the class convenient to use.  Rather than explain everything, though, I'll just post some code and let you figure out what it does.  Pay particular attention to my comment above one of the methods, as it discusses my reasons for breaking the rules I just laid out.

main.cpp:

#include
#include
#include "String.hpp"

using std::cout;
using std::endl;

int main()
{
  String s1("Hello"), s2("world!");
  cout << s1 << ", " << s2 << endl;
  s2[0] = 'W';
  cout << s1 << ", " << s2 << endl;
  s1[0] = s1[2] = s1[4] = 'M';
  cout << s1 << ", " << s2 << endl;

  const char *cs1 = s1, *cs2 = s2;
  cout << cs1 << ", " << cs2 << endl;

  return 0;
}


String.hpp:

#ifndef STRING_HPP_
#define STRING_HPP_

#include

class CharRef
{
  char &_data;

public:
  explicit CharRef(char &data) : _data(data) {}
  CharRef(const CharRef &rhs) : _data(rhs._data) {}

  CharRef operator=(const char rhs);
  CharRef operator=(const CharRef &rhs);
  operator const char() const { return _data; }
  operator char() const { return _data; }
};

class String
{
  char *_data;

public:
  explicit String(const char *data="");
  String(const String &rhs);
  ~String() { delete [] _data; }

  String &operator=(const char *rhs);
  String &operator=(const String &rhs);
  CharRef operator[](int index);
  char operator[](int index) const;

  // This is actually unsafe, but we need it for convenience, unless we really
  // feel like copying all data twice.  BE WARNED!  When this class reallocates
  // memory, all old references to _data are invalid!
  operator const char*() const { return _data; }
};

#endif


String.cpp:

#include "String.hpp"

#include
#include
using std::cout;
using std::endl;

CharRef CharRef::operator=(const char rhs)
{
  _data = rhs;
  return *this;
}

CharRef CharRef::operator=(const CharRef &rhs)
{
  return operator=(rhs._data);
}

String::String(const char *data)
{
  _data = new char[1];
  _data[0] = '\0';
  operator=(data);
}

String::String(const String &rhs)
{
  _data = new char[1];
  _data[0] = '\0';
  operator=(rhs);
}

String &String::operator=(const char *rhs)
{
  char *tmp = new char[strlen(rhs)+1];
  strcpy(tmp, rhs);
  delete [] _data;
  _data = tmp;

  return *this;
}

String &String::operator=(const String &rhs)
{
  return operator=(rhs._data);
}

char String::operator[](int index) const
{
  return _data[index];
}

CharRef String::operator[](int index)
{
  return CharRef(_data[index]);
}


Of particular note in the String class is that we use "CharRef operator[](int index);" rather than "char &operator[](int index);".  Why is that?

Put each of those into files main.cpp, String.hpp, and String.cpp, respectively.  Then, assuming you have GCC, run "g++ -Wall -Wshadow -ansi -pedantic -o demo String.cpp main.cpp".

Enjoy, and feel free to ask any questions you might have after having tried to understand the code.
William Grim
IT Associate, Morgan Stanley

William Grim

Well, no one said anything.  I assume it's too boring for everyone, and that's okay :-)  Hopefully someone will find it useful at some point, and it's been updated to fix a couple bugs that showed up in its rush development.

I would like to say a couple things about the use of ideas like this though.  One, my code is less efficient than a lot of other, less safe code that can be created.  The point here is just to demonstrate how to do this; your job will be to find areas where the solution fits the problem.  The aim should always be appropriate trade-offs between high performance code and "safe" code, where "safe" means protecting users from themselves.
William Grim
IT Associate, Morgan Stanley

Justin Camerer

Justin Camerer
Do yo' chain hang low?

William Grim

Quoteiamjwc wrote:
I enjoyed it, Mike.

Aww, you're so nice :-)  *hugs all around*
William Grim
IT Associate, Morgan Stanley

Gregory Bartholomew

......

William Grim

QuoteTalmai wrote:
You lost me with "MeMlM".

Haha, but did I have you at "Hello?"
William Grim
IT Associate, Morgan Stanley