C + + Primer Learning Notes _20_ class and Data Abstraction (6) _ Deep copy and shallow copy, empty class and empty array
One, deep copy and shallow copy
Shallow copy: All variables of the copied object contain the same value as the original object, and all references to other objects still point to the original object. In other words, a shallow copy simply duplicates the object being considered, not the object it refers to.
Deep copy: All the variables of the copied object contain the same values as the original object, removing the variables that refer to other objects. Variables that refer to other objects will point to new objects that have been copied, not those that are already referenced. In other words, a deep copy copies the objects referenced by the object to be copied again.
A shallow copy may cause a run-time error, especially during object creation and deletion.
To put it simple, suppose a class has pointer members, and if it just allocates the memory of the pointer itself, it is a shallow copy , as in. If the memory that the pointer points to is also allocated at the time of the copy, it is called a deep copy , such as (T is copied from s).
"For instance."
struct test{ char *ptr;}; void Shallow_copy (test& src, test& dest) { dest.ptr = src.ptr;} void Deep_copy (test& src, test& dest) { dest.ptr = malloc (strlen (src.ptr) + 1); memcpy (Dest.ptr, src.ptr);}
The problem with a shallow copy is that there are two pointers pointing to the same block of memory, and delete one of the pointers, then the remaining pointers become wild pointers . The default copy constructor and assignment operators for a compiler composition are shallow copies, and shallow copies are also possible if they are only assigned to ordinary members.
#include <string.h> #include <cstring> #include <iostream>using namespace Std;class string{public:st Ring (char *str = ""); ~string (); String (const string &other); String & operator= (const string &other); void Display ();p Rivate:char *allocandcpy (char *str); char *str_;}; String::string (char *str/* = */) {str_ = allocandcpy (str);} String::~string () {delete[] str_;} string::string (const String &other) {str_ = allocandcpy (OTHER.STR_);} String &string:: operator = (const String &other) {if (this = = &other) return * this; Delete[] Str_; Str_ = allocandcpy (OTHER.STR_); return * this;} Char *string::allocandcpy (char *str) {int len = strlen (str) + 1; Char *tmp = new Char[len]; memset (tmp, 0, Len); strcpy (TMP, str); return TMP;} void String::D isplay () {cout << str_ << Endl;} int main (void) {String S1 ("AAA"); S1. Display (); String s2 = S1; Call Copy ConstructBuild function//The default copy constructor provided by the system implements a shallow copy of s2.str_ = S1.str_ String S3; S3. Display (); s3 = S2; Calling the Equals operator//The default equals operator provided by the system implements a shallow copy of s3.str_ = S2.str_; s3.operator= (S2); S3. Display (); To make the object unique, we prohibit the copy//method from declaring the copy constructor with the = operator as private and not providing their implementation of return 0;}
Operation Result:
AAAAAA
Explanation: The string class in the above program has a char* STR_ member, so a deep copy is implemented so that it does not cause the memory to be freed two times, or the memory pointed by the pointer will affect the error of the other object. In addition, if we want to make the object unique, we need to suppress the copy, just declare the copy constructor and the equals operator as private and do not provide their implementation.
Note: When writing assignment functions for derived classes, do not forget to reassign the data members of the base class, which can be implemented by calling the base class's assignment function, such as
Base::operator= (other) is called in derived& derived::operator= (const derived& Other) {};
Two, empty and empty arrays
Null class Default-generated members:
Class Empty {}; Empty (); Default constructor Empty (const empty&);//Default copy constructor ~empty (); Default destructor empty& operator= (const empty&); The default assignment operator empty* operator& (); Accessor operator Const empty* operator& () const; Accessor operator const
"Example"
#include <iostream>using namespace Std;class empty{public: Empty * operator& () { cout < < "AAAA" << Endl; return this ; } Const EMPTY * operator& () const { cout << "BBBB" << Endl; return this ; }}; int main (void) { Empty e; Empty *p = &e; Equivalent to e.operator& (); Const EMPTY E2; Const Empty *P2 = &e2; cout << sizeof (Empty) << Endl; return 0;}
Operation Result:
Aaaa
BBBB
1
Explanation: You can see that the two fetch operator functions are called separately, and the size of the empty class is 1 bytes.
Example
Experience the following program results:
#include <iostream>using namespace Std;int main () { int a[0]; Class B {}; struct C { int m; int N; Char buffer[]; }; Class D { int s[0]; }; cout << "sizeof (a) =" << sizeof (a) << Endl; 0 cout << "b{}=" << sizeof (B) << Endl; 1 cout << "c=" << sizeof (C) << Endl; 8 cout << "d=" << sizeof (D) << Endl; 0 return 0;}
Operation Result:sizeof (a) =0
B{}=1
C=8
d=0
Reference:
C + + Primer Fourth Edition
Effective C + + 3rd
http://blog.csdn.net/jnu_simba/article/details/9183425
http://blog.csdn.net/zjf280441589/article/details/24954205
C + + Programming specification
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
C + + Primer Learning Notes _20_ class and Data Abstraction (6) _ Deep copy and shallow copy, empty class and empty array