Copy and Assign: The Instantiation Paradox


Dialogue 1002: On the Rule of Three

Note: This dialogue is a work-in-progress!!! Don't put much stock into it until you see the checked box on the previous page. Also note that it is imaginary.



Introduction: The Biggest Misconception

| simplicio | Hello sunsaengnim. I have another question for you today. A friend once casually told me that C++ was just like C with classes...
| salviati | Allow me to stop you right there. This simply isn't true. I have spoken many times about how C++ is not like C, not even a little bit.
| simplicio | Huh, really? That might explain my results...

Takeaway 1: Overloading of the '=' character

| simplicio | Suppose I have the following program:
#include <iostream>
#include <list>

class TestC {
public:
TestC(size_t _id) {
id = _id;
for (size_t iterator = 0; iterator < id; iterator ++) {
components.push_back(iterator);
}
}
TestC(const TestC &other) {
std::cout << "Copy constructor" << std::endl;
id = other.id;
}
~TestC() { }
TestC *operator =(const TestC &other) {
std::cout << "Assignment" << std::endl;
this->id = other.id;
return this;
}

size_t id;
std::list components;
};

int main() {
TestC obj{17};
TestC obj2 = obj;
obj2.id = 19;
std::cout << "first obj:" << obj.id << std::endl;
std::cout << "second obj:" << obj2.id << std::endl;
return 0;
}

| simplicio | When I run the program, it outputs "Copy constructor" and does not even execute the `=` operator!! How could this be??
| salviati | This is the biggest lie that people ever tell about C++: that it is fundamentally compatible with C.
| ________ | As it turns out, the truth is that the `=` symbol is overloaded and in this case invokes a Copy Constructor,
| ________ | rather than invoking the assignment operator.
| ________ | For this reason and others, the language is radically different from C. Never forget this!

Takeaway 2: allocation

| simplicio | Well, I sure am glad I didn't spend years under that misconception!
| _________ | So, the next mystery is, where is that object allocated? I thought it would be on the stack, and yet it's not...
| _________ | ...or is it?
| salviati | Aha. Good question, young grasshopper. Let me show you a MCVE...
class WhereAmIAllocated {
float x;
std::list nested;
};
int main() {
WhereAmIAllocated testObj{};
return 0;
}

| salviati | That std::list is a part of the standard template. Therefore, its memory is managed "automatically" by the C++ compiler.
| salviati | And that's what makes all the difference, as a matter of fact. If we commented out that list, we would have all our allocations done on the stack.

class WhereAmIAllocated {
float x;
};
int main() {
WhereAmIAllocated testObj{};
return 0;
}

This discussion is imaginary! If you see a problem/error in it, then take it up with me.