If we want to copy an array of objects whose element type is T to another array, we can easily write the following code:
T sour [N];
T dest [N];
Int I;
For (I = 0; I <N; I ++)
Dest [I] = sour [I];
In C and C ++, the above Code can take effect.
However, C programmers may prefer the following solution:
T sour [N];
T dest [N];
Int I;
Memcpy (dest, sour, N * sizeof (T ));
This method works well in C. However, if T is a non-basic type, the above Code may cause a disaster in C ++, because memcpy is a bitwise copy, this involves the issue of deep copy and shallow copy.
If type T has the following features, you cannot use memcpy for it.
1. type T needs to explicitly define the copy constructor and value assignment operator
2. type T does not need to explicitly define the copy constructor and value assignment operator, but its underlying data members need to explicitly define the copy constructor and value assignment operator
Refer to the following code
# Include <iostream>
# Include <string>
Using namespace std;
// The reason why the memcpy function cannot be used for B is obvious.
Class B
{
Public:
Int *;
B (int m = 0)
{
Cout <"B constructor" <endl;
A = new int;
* A = m;
}
B (const B & B)
{
Cout <"B's replication constructor" <endl;
A = new int;
* A = * (B. );
}
B & operator = (const B & B)
{
Cout <"call B's value assignment operator" <endl;
If (& B! = This)
{
Delete;
A = new int;
* A = * (B. );
}
Return * this;
}
~ B ()
{
Cout <"calls B's destructor" <endl;
Delete;
}
};
// A does not need to define the copy constructor, value assignment operator, and destructor, but does not need to use the mencpy function for.
Class
{
Public:
B B;
A (int m = 0): B (m ){}
};
Void main ()
{
A a1 (1 );
A a2 (2 );
Cout <"test whether A requires A value assignment operator" <endl;
Cout <"a1:" <a1. B. a <"" <* (a1. B. a) <endl;
Cout <"a2:" <a2. B. a <"" <* (a2. B. a) <endl;
A1 = a2;
// Memcpy (& a1, & a2, sizeof (A); // do not call the bitwise copy function such as memcpy for.
Cout <"a1:" <a1. B. a <"" <* (a1. B. a) <endl;
Cout <"a2:" <a2. B. a <"" <* (a2. B. a) <endl;
Cout <"test whether A copies constructor" <endl;
A a3 (1 );
Cout <"a3:" <a3. B. a <"" <* (a3. B. a) <endl;
A a4 (a3 );
Cout <"a4:" <a4. B. a <"" <* (a4. B. a) <endl;
}
Running result
Constructor B
Constructor B
Test whether A requires A value
A1: 00036208 1
A2: 00036238 2
Call the value assignment operator of B.
A1: 00036208 2
A2: 00036238 2
Test whether A copies the constructor.
Constructor B
A3: 000362E0 1
B's replication Constructor
A4: 00036310 1
Call the destructor of B
Call the destructor of B
Call the destructor of B
Call the destructor of B
Note: The default value assignment operator and the copy constructor recursively depend on the replication and value assignment definitions of the underlying class members. It not only implements bitwise replication as the structure in C version, it only implements bitwise replication for inner-type member variables. The default destructor also recursively depends on the destructor of the underlying class.
From yucan1001