bitwise copy / shallow copy

Is a bitwise copy the same as a shallow copy. I am currently reading about shallow / deep copies which are terms I have never came across before, but the information relating to it is stuff I have covered before but in a very old text book. And this text book referred to it as a bitwise copy, it sounds similar to what the shallow copy is being described as, but I am not sure if it is the exact same thing?

If you are doing a shallow copy, one method is to do a bit-wise copy of the class. This may appear to work but has issues that will bite at some point. It's never recommended to do a bit-wise copy of the whole class. Do a simple (shallow) copy of the class variables.

To determine if a shallow or deep copy is needed, see if the class uses dynamic memory allocation. If it does, you need deep copy otherwise a shallow copy is ok.
So what I have gotten from reading the link, and from what seeplus said, a shallow copy is a bitwise copy, and a deep copy would be a member wise copy. But on the learncpp website, it states this
"Because C++ does not know much about your class, the default copy constructor and default assignment operators it provides use a copying method known as a memberwise copy (also known as a shallow copy)."

Is that wrong, or am I misunderstanding what it is saying. To me, that is saying a memberwise copy is a shallow copy, and not a deep copy.
Take a simple class:
1
2
3
struct Example {
  int* ptr;
};

Now, lets play:
1
2
3
4
5
6
Example one;
int answer {42};
one.ptr = &answer;

Example two;
// bitwise copy memory of one to memory of two 

The memory of an Example contains just one pointer.
The memory of one contains address of answer.
After bitwise copy the memory of two contains same bits, the address of answer.

1
2
3
4
// copy construct:
Example three { one };
// assert: *(one.ptr) == *(three.ptr) == 42
// assert: one.ptr == three.ptr 

Default copy constructor does copy each member, like if we had written:
1
2
3
Example::Example( const Example& rhs )
 : ptr( rhs.ptr )
{}

The issue here is that copy construction of simple type, like pointer ptr is in practice a bitwise copy.

Hence, for class Example, the default copy constructor is no different from bitwise copy.

All instances, one, two, three point to same integer. The copies are shallow.

If the Example should own the memory that it points to, then a copy should not point to same memory. The copy ctor could be:
1
2
3
4
5
Example::Example( const Example& rhs )
 : ptr( new int )
{
  *ptr = *rhs.ptr; // deep copy of member data
}



Take another class:
1
2
3
struct Sample {
  std::vector<int> vec;
};

Now, lets play:
1
2
3
4
5
6
Sample uno;
uno.vec.push_back( 42 );

Example duo( duo );
// assert: uno.vec[0] == duo.vec[0] == 42
// assert: &(uno.vec[0]) != &(duo.vec[0]) 

The default copy constructor that makes a shallow copy of a class that has raw pointers
does a proper deep copy of a class that has "sugar-coated pointer", aka vector.
Last edited on
Topic archived. No new replies allowed.