简体   繁体   中英

bit by bit definition (c++ shallow copy)

so I have an exam soon, and glancing through my notes, the teacher says that a shallow copy is defined as a bit by bit copy. I know all about shallow and deep copies, yet I have no idea what bit by bit copy is supposed to mean. Isn't all computer data stored as bits? Could this definition imply that during a shallow copy, a bitstream is implemented when copying the data? Anybody know stuff about this "bit by bit" terminology? Thanks

Say you have two variables MyObj a, b; . If a = b performs a shallow copy, then the bits in the variable b will now be the same as the bits in the variable a . In particular, if MyObj contains any pointers or references, they are the same in both a and b . The objects which are pointed or referred to are not copied.

Bit by bit copy / Shallow copy

Take for example a pointer pointing to a chunk of data:

int* my_ints = new int[1000];

my_ints point to the start of an area of memory which spans a thousand int s.

When you do

int* his_ints = my_ints;

the value of my_ints is copied to his_ints , ie the bits of my_ints is copied to his_ints . This means that his_ints also points to the start of the same area of memory which my_ints also points. Therefore by doing

his_ints[0] = 42;

my_ints[0] will also be 42 because they both point to the same data. That is what your professor is most probably referred to as "bit by bit" copying, which is also commonly called as "shallow copy". This is mostly encountered when copying pointers and references (you can't technically copy references, but you can bind a reference to a variable bound to another reference).

Deep copy

Now, you may not want to have the bit by bit copy behavior. For example, if you want a copy and you want to modify that copy without modifying the source. For this, you do a deep copy.

int* my_ints = new int[1000];
int* his_ints = new int[1000];
std::copy(my_ints, my_ints + 1000, his_ints);

std::copy there copies the int s in the area of memory pointed to by my_ints into the area of memory pointed to by his_ints . Now if you do

my_ints[0] = 42;
his_ints[0] = 90;

my_ints[0] and his_ints[0] will now have different values, as they now point to their respective and different areas of memory.

How does this matter in C++?

When you have your C++ class, you should properly define its constructor. The one constructor that is relevant with the topic is the copy constructor (note: this also applies to the copy assignment operator). If you only let the compiler generate the default copy constructor, it simply does shallow copies of data, including pointers that may point to areas of memory.

class Example {
public:
    int* data;

    Example() {
       data = new int[1000];
    }

    Example(const Example&) = default;   // Using C++11 default specifier

    ~Example() {
       delete[] data;
    }
};

// Example usage
{
   Example x;
   Example y = x;   // Shallow copies x into y
   assert(x.data == y.data);
   // y's destructor will be called, doing delete[] data.
   // x's destructor will be called, doing delete[] data;
   //   This is problematic, as you are doing delete[] twice on the same data.
}

To solve the problem, you must perform a deep copy of the data. For this to be done, you must define the copy constructor yourself.

Example(const Example& rhs) {
   data = new int[1000];
   std::copy(data, data + 1000, rhs.data);
}

For more info and better explanation, please see What is The Rule of Three? .

I would define a bit-by-bit copy as the transfer of the information allocated to an object as an unstructured block of memory. In the case of simple structs this is easy to imagine.

What are the contents of the source struct? Are they initialized? What are its relationships to other objects? All unimportant.

In some sense, a bit-by-bit copy is like a shallow copy in that like a shallow copy a bit-by-bit copy will not duplicate related objects, but that's because it doesn't even consider object relationships.

For example C++ defines a trivial copy constructor as

A trivial copy constructor is a constructor that creates a bytewise copy of the object representation of the argument, and performs no other action. Objects with trivial copy constructors can be copied by copying their object representations manually, eg with std::memmove. All data types compatible with the C language (POD types) are trivially copyable.

In contrast, shallow copy and its counter-part deep copy exist as a concept precisely because of the question of object relationships.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM