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.