S R T B H P N

PointersAndReferences.cpp, PointersAndReferences.txt, Code folder

This demo illustrates how pointers and references are used in C++ code. We've demonstrated std::unique_ptr and std::shared_ptr as well as native pointers.

PointersAndReferences.cpp

/////////////////////////////////////////////////////////////////
// PointersAndReferences.cpp - demonstration                   //
//                                                             //
// Jim Fawcett, CSE687 - Object Oriented Design, Summer 2017   //
/////////////////////////////////////////////////////////////////
/*
 * This package demonstrates access to variables defined in the
 * static, stack, and native heap memory regions.
 * - Variables declared as static reside in static memory and 
 *   live for the duration of the program.
 * - Non-static variables reside in the stack frame of their local
 *   scope and are destroyed when the thread of execution leaves
 *   that scope.
 * - Variables created with new reside in the native heap and are
 *   destroyed when delete is called on their addresses.
 */
#include <string>
#include <iostream>
#include <memory>
#include "../Utilities/Utilities.h"

///////////////////////////////////////////////////////////
// Demonstration class
class Demo
{
public:
  using Message = std::string;
  Demo(const Message& msg) : msg_(msg) {}
  ~Demo()
  {
    putLine("destroying " + this->message());
  }
  Message& message()
  {
    return msg_;
  }
  Message countedMessage()
  {
    static size_t count = 0;  // executed only once on initial call, 
                              // creating initialized variable in static memory
    ++count;
    Message temp = "#" + Convert<size_t>::toString(count) + " " + msg_;
    return temp;
  }
private:
  Message msg_;
};

///////////////////////////////////////////////////////////
// Demonstration

Cosmetic cosmetic("note order of destruction");

int main()
{
  putTitle("Demonstrating Pointers and References", '=');
  putLine();

  putTitle("declare instance of custom class Demo");
  Demo demo("demo");         // created in main's stack frame
  putLine(demo.countedMessage());
  putLine();

  putTitle("declare and use pointer to demo");
  Demo* pDemo = &demo;       // pointer to instance in stack memory so don't delete
  putLine(pDemo->countedMessage());
  putLine();

  putTitle("declare and use reference to demo");
  Demo& rDemo = demo;
  putLine(rDemo.countedMessage());
  putLine();

  putTitle("declare and use pointer to Demo instance on heap");
  pDemo = new Demo("demo on heap");  // pointer to instance in heap, so delete
  putLine(pDemo->countedMessage());
  delete pDemo;
  putLine();

  putTitle("declare and use reference to Demo instance on heap");
  Demo& rHeapDemo = *new Demo("demo on heap");  // reference to instance in heap, so delete
  putLine(rHeapDemo.countedMessage());
  delete &rHeapDemo;
  putLine();

  putTitle("you can declare and use reference to reference to a temporary");
  Demo&& rrDemo = Demo("another Demo instance");  // in stack memory so don't delete
  putLine(rrDemo.countedMessage());
  putLine();

  putTitle("declare a unique_ptr to refer to heap allocation with automatic destruction");
  std::unique_ptr<Demo> uPtr(new Demo("referenced by std::unique_ptr"));  // don't call delete, uPtr will
  putLine(uPtr->countedMessage());
  putLine();

  putTitle("declare a shared_ptr sharing a reference counted heap allocation");
  std::shared_ptr<Demo> sPtr1(new Demo("demo referenced by std::shared_ptr sPtr1"));  // don't call delete
  putLine(sPtr1->countedMessage());
  putLine();

  putTitle("declare a shared_ptr sharing a reference counted heap allocation");
  std::shared_ptr<Demo> sPtr2(sPtr1);   // this is how you share an allocation
  sPtr2->message() = "demo referenced by std::shared_ptr sPtr2";
  putLine(sPtr2->countedMessage());
  putLine();

  putLine("---- end of main ----");
}