///////////////////////////////////////////////////////////////// // PointersAndReferences.cpp - demonstration // // // // Jim Fawcett, CSE687 - Object Oriented Design, Summer 2017 // ///////////////////////////////////////////////////////////////// /* * This package demonstrates access to variables defined in the * static, stack, or 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 #include #include #include "Utilities.h" /////////////////////////////////////////////////////////// // Demonstration class class Demo { public: using Message = std::string; Demo(const Message& msg) : msg_(msg) {} ~Demo() { Utilities::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 = "#" + Utilities::Convert::toString(count) + " " + msg_; return temp; } private: Message msg_; }; /////////////////////////////////////////////////////////// // Demonstration Utilities::Cosmetic cosmetic("note order of destruction"); int main() { Utilities::putTitle("Demonstrating Pointers and References", '='); Utilities::putLine(); Utilities::putTitle("declare instance of custom class Demo"); Demo demo("demo"); // created in main's stack frame Utilities::putLine(demo.countedMessage()); Utilities::putLine(); Utilities::putTitle("declare and use pointer to demo"); Demo* pDemo = &demo; // pointer to instance in stack memory so don't delete Utilities::putLine(pDemo->countedMessage()); Utilities::putLine(); Utilities::putTitle("declare and use reference to demo"); Demo& rDemo = demo; Utilities::putLine(rDemo.countedMessage()); Utilities::putLine(); Utilities::putTitle("declare and use pointer to Demo instance on heap"); pDemo = new Demo("demo on heap"); // pointer to instance in heap, so delete Utilities::putLine(pDemo->countedMessage()); delete pDemo; Utilities::putLine(); Utilities::putTitle("declare and use reference to Demo instance on heap"); Demo& rHeapDemo = *new Demo("demo on heap"); // reference to instance in heap, so delete Utilities::putLine(rHeapDemo.countedMessage()); delete &rHeapDemo; Utilities::putLine(); Utilities::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 Utilities::putLine(rrDemo.countedMessage()); Utilities::putLine(); Utilities::putTitle("declare a unique_ptr to refer to heap allocation with automatic destruction"); std::unique_ptr uPtr(new Demo("referenced by std::unique_ptr")); // don't call delete, uPtr will Utilities::putLine(uPtr->countedMessage()); Utilities::putLine(); Utilities::putTitle("declare a shared_ptr sharing a reference counted heap allocation"); std::shared_ptr sPtr1(new Demo("demo referenced by std::shared_ptr sPtr1")); // don't call delete Utilities::putLine(sPtr1->countedMessage()); Utilities::putLine(); Utilities::putTitle("declare a shared_ptr sharing a reference counted heap allocation"); std::shared_ptr sPtr2(sPtr1); // this is how you share an allocation sPtr2->message() = "demo referenced by std::shared_ptr sPtr2"; Utilities::putLine(sPtr2->countedMessage()); Utilities::putLine(); Utilities::putLine("---- end of main ----"); }