fork download
  1. #include <iostream>
  2. #include <cstdint>
  3.  
  4. struct Object
  5. {
  6. int m_i;
  7.  
  8. void event(const char* what, const char* where)
  9. {
  10. std::cout <<
  11. what<< " " << (void*)this <<
  12. " value " << m_i <<
  13. " via " << where <<
  14. std::endl;
  15. }
  16.  
  17. // Construct an object with a specific value.
  18. Object(int i) : m_i(i)
  19. {
  20. event("Constructed", "Operator(int i)");
  21. }
  22.  
  23. // This is called the copy constructor, create one object from another.
  24. Object(const Object& rhs) : m_i(rhs.m_i)
  25. {
  26. event("Constructed", "Operator(const Object&)");
  27. }
  28.  
  29. // This is how to handle Object o1, o2; o1 = o2;
  30. Object& operator=(const Object& rhs)
  31. {
  32. m_i = rhs.m_i;
  33. event("Assigned", "operator=");
  34. return *this;
  35. }
  36.  
  37. // Handle destruction of an instance.
  38. ~Object() { event("Destructed", "~Object"); }
  39. };
  40.  
  41. void foo1(Object o)
  42. {
  43. std::cout << "Entered foo1, my o has value " << o.m_i << std::endl;
  44. // poke our local o
  45. o.m_i += 42;
  46. std::cout << "I changed o.m_i, it is " << o.m_i << std::endl;
  47. }
  48.  
  49. void foo2(Object* o)
  50. {
  51. std::cout << "Foo2 starts with a pointer, it's value is " << (uintptr_t)o << std::endl;
  52. std::cout << "That's an address: " << (void*)o << std::endl;
  53. std::cout << "m_i of o has the value " << o->m_i << std::endl;
  54. o->m_i += 42;
  55. std::cout << "I've changed it tho, now it's " << o->m_i << std::endl;
  56. }
  57.  
  58. void foo3(Object& o)
  59. {
  60. std::cout << "foo3 begins with a reference called o, " << std::endl <<
  61. "which is sort of like a pointer but the compiler does some magic " << std::endl <<
  62. "and we can use it like a local concrete object. " <<
  63. std::endl <<
  64. "Right now o.m_i is " << o.m_i <<
  65. std::endl;
  66. o.m_i += 42;
  67. std::cout << "Only now, it is " << o.m_i << std::endl;
  68. }
  69.  
  70. void foo4(Object*& o)
  71. {
  72. std::cout << "foo4 begins with a reference to a pointer, " << std::endl <<
  73. "the pointer has the value " << (uintptr_t)o << " which is " <<
  74. (void*)o <<
  75. std::endl <<
  76. "But the pointer points to an Object with m_i of " << o->m_i << std::endl <<
  77. "which we accessed with '->' because the reference is to a pointer, " <<
  78. "not to an Object." <<
  79. std::endl;
  80. o->m_i += 42;
  81. std::cout << "I poked o's m_i and now it is " << o->m_i << std::endl;
  82. // Now for something really dastardly.
  83. o = new Object(999);
  84. std::cout << "I just changed the local o to point to a new object, " <<
  85. (uintptr_t)o << " or " << (void*)o << " with m_i " << o->m_i <<
  86. std::endl;
  87. }
  88.  
  89. int main()
  90. {
  91. std::cout << "Creating our first objects." << std::endl;
  92. Object o1(100), o2(200);
  93.  
  94. std::cout << "Calling foo1 with o1" << std::endl;
  95. foo1(o1);
  96. std::cout << "back in main, o1.m_i is " << o1.m_i << std::endl;
  97.  
  98. std::cout << "Calling foo2 with &o1" << std::endl;
  99. foo2(&o1);
  100. std::cout << "back in main, o1.m_i is " << o1.m_i << std::endl;
  101.  
  102. std::cout << "Calling foo3(o2), which looks like the way we called foo1." << std::endl;
  103. foo3(o2);
  104. std::cout << "back in main, o2.m_i is " << o2.m_i << std::endl;
  105.  
  106. std::cout << "Creating our pointer." << std::endl;
  107. Object* optr;
  108. std::cout << "Setting it to point to 'o2'" << std::endl;
  109. optr = &o2;
  110. std::cout << "optr now has the value " << (uintptr_t)optr <<
  111. " which is the address " << (void*)optr <<
  112. " which points to an Object with m_i = " << optr->m_i <<
  113. std::endl;
  114.  
  115. foo4(optr);
  116.  
  117. std::cout << "back in main, o2 has the value " << o2.m_i << std::endl <<
  118. "and now optr has the value " << (uintptr_t)optr << std::endl <<
  119. "and optr->m_i is now " << optr->m_i <<
  120. std::endl;
  121.  
  122. if (optr != &o2)
  123. delete optr; // otherwise we'd technically be leaking memory.
  124.  
  125. return 0;
  126. }
Success #stdin #stdout 0s 3036KB
stdin
Standard input is empty
stdout
Creating our first objects.
Constructed 0xbfd60b60 value 100 via Operator(int i)
Constructed 0xbfd60b64 value 200 via Operator(int i)
Calling foo1 with o1
Constructed 0xbfd60b68 value 100 via Operator(const Object&)
Entered foo1, my o has value 100
I changed o.m_i, it is 142
Destructed 0xbfd60b68 value 142 via ~Object
back in main, o1.m_i is 100
Calling foo2 with &o1
Foo2 starts with a pointer, it's value is 3218475872
That's an address: 0xbfd60b60
m_i of o has the value 100
I've changed it tho, now it's 142
back in main, o1.m_i is 142
Calling foo3(o2), which looks like the way we called foo1.
foo3 begins with a reference called o, 
which is sort of like a pointer but the compiler does some magic 
and we can use it like a local concrete object. 
Right now o.m_i is 200
Only now, it is 242
back in main, o2.m_i is 242
Creating our pointer.
Setting it to point to 'o2'
optr now has the value 3218475876 which is the address 0xbfd60b64 which points to an Object with m_i = 242
foo4 begins with a reference to a pointer, 
the pointer has the value 3218475876 which is 0xbfd60b64
But the pointer points to an Object with m_i of 242
which we accessed with '->' because the reference is to a pointer, not to an Object.
I poked o's m_i and now it is 284
Constructed 0x8e32008 value 999 via Operator(int i)
I just changed the local o to point to a new object, 149102600 or 0x8e32008 with m_i 999
back in main, o2 has the value 284
and now optr has the value 149102600
and optr->m_i is now 999
Destructed 0x8e32008 value 999 via ~Object
Destructed 0xbfd60b64 value 284 via ~Object
Destructed 0xbfd60b60 value 142 via ~Object