"shallow" versus "deep" copy is less meaningful in C++ than it is in C or Java.
To illustrate this, I've changed your Foo
class from three int
s to an int
, an int*
, and a vector<int>
:
#include <iostream>
#include <vector>
class Foo {
public:
int a;
int *b;
std::vector<int> c;
};
using namespace std;
int main() {
Foo f1, f2;
f1.a = 42;
f1.b = new int(42);
f1.c.push_back(42);
f2 = f1;
cout << "f1.b: " << f1.b << " &f1.c[0]: " << &f1.c[0] << endl;
cout << "f2.b: " << f2.b << " &f2.c[0]: " << &f2.c[0] << endl;
}
When this program is run, it yields the following output:
f1.b: 0x100100080 &f1.c[0]: 0x100100090
f2.b: 0x100100080 &f2.c[0]: 0x1001000a0
The int
is boring, so I've left it out. But look at the difference between the int*
and the vector<int>
: the int*
is the same in f1 and f2; it's what you would call a "shallow copy". The vector<int>
however is different between f1 and f2; it's what you would call a "deep copy".
What's actually happened here is that the default operator =
in C++ behaves as if the operator =
for all of its members were called in order. The operator =
for int
s, int*
s, and other primitive types is just a byte-wise shallow copy. The operator =
for vector<T>
performs a deep copy.
So I would say the answer to the question is, No, the default assignment operator in C++ does not perform a shallow copy. But it also doesn't perform a deep copy. The default assignment operator in C++ recursively applies the assignment operators of the class's members.