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 ----");
}