As far as I know, "shallow copy" is not
...if I modify one value after the assignment both objects get modified.
Shallow copy of any value(pointer) is simply a copy of a value(pointer).
Shallow copy of some class object is just a memberwise copy.
Default assignment operator does the trick.
In case if you came from a C#-like land:
When you write
Object o1;
Object o2;
you have already created two indepenent objects in memory (on stack).
And when you write
o2 = o1;
by default you do a shallow copy: just copy all data stored in a chunk of memory corresponding to o1 to the memory corresponding to o2. As simple as that. And essentially C# does the same, the only difference is that o1 and o2 are references there. So you just copy a value of one reference (not the value reference is referring to!) to another reference.
So the point is that it is all not about
...implementing assignment operator.
but copying references or object values itself.
In c++ writing o1
you get the object value, not reference to the object.
Moreover, in c++ you can not copy references. But what you can is copying pointer.
Object* o1 = new Object;
Object* o2;
o2 = o1; // now pointing to the same object
But keep in mind, c++ does not have a GC, so each time you allocate memory on heap you must dealocate it later by yourself (unless you use smart pointers but that is another topic).