the
difference of & used in reference and store
address
A reference & is a alias of variable and must be
initialized before we use it, eg: 1
2
3
4int a=6;//initialization
int &b=a;
cout << b <<endl;
// output is 6& is used to store address, it should be used in
conjunction with a pointer, eg: 1
2
3int *x;
x = &a;
//or int *x = &aNULL as default.
tips: in the initialization of a pointer,
int *can be regarded as a pointer type simply.
copy constructor
copy constructor is typically used for: 1. initializing
object by using same type object 2. copying object and send it to
function as parameter 3. copying object and return the object from
function Typical format of copy constructor is:
1
2
3
4classname(const classname &obj)
{
//the body of constructor
}
deep copy using a copy constructor
define a copy constructor and ensure deep copy of dynamically allocated buffers
1 |
|
code analysis
To start with, let’s focus on main() that (as before)
creates an object sayHello in Line 58
MyString SayHello("Hello ");. Creating
sayHello results in the first line of output that comes
from the constructor of MyString, at Line 12. For sake of
convenience, the constructor also displays the memory address that
buffer points to. main() then passes sayHello
by value to function UseMyString() in Line 59
UseMyString(SayHello);, which automatically results in the
copy constructor being invoked as shown in the output. The code in the
copy constructor is similar to that in the constructor. The basic idea
is the same, check the length of C-style string buffer
contained in the copy source at Line 27
buffer = new char[strlen(copySource.buffer) + 1];, allocate
proportional memory in one’s own instance of buffer, and then use
strcpy to copy from source to destination at Line 28
strcpy(buffer, copySource.buffer);. This is not a shallow
copy of pointer values. This is a deep copy where the content being
pointed to is copied to a newly allocated buffer that
belongs to this object.
the memory address being pointed to by buffer is
different in the copy—that is, two objects don’t point to the same
dynamically allocated memory address. As a result, when function
UseMyString() returns and parameter str is destroyed, the
destructor code does a delete[]on the memory address that
was allocated in the copy constructor and belongs to this object. In
doing so, it does not touch memory that is being pointed to by
sayHello in main(). So, both functions end and
their respective objects are destroyed successfully and peacefully
without the application crashing.