Object Copy¶
Copy in C¶
Copy of objects in C: struct
struct point
{
int x;
int y;
};
|
struct point p1 = {2,7};
struct point p2;
p2 = p1;
|
struct point
: memberwise copySimple: transfer of memory image
Copy Constructor¶
Copying objects in C: similar to C++
class point
{
// ...
};
...
point p1;
point p2(p1);
|
|
But …
Copy Constructor and Pointer Members (1)¶
Caution, Trap: pointer members
class String
{
public:
String(const char *c_str);
private:
char *_c_str;
};
String s1("hello");
String s2 = s1; // ctor!
|
Copy Constructor and Pointer Members (2)¶
Segmentation Fault in the best of all cases …
|
Copy Constructor and Pointer Members (3)¶
Solution
Explicit copy constructor
Copy the memory pointed to
String::String(const String& s)
{
_c_str = new char[
strlen(s._c_str)+1];
strcpy(_c_str, s._c_str);
}
|
Copy Constructor: Recursive/Memberwise¶
struct TwoStrings
{
String s1;
String s2;
};
struct TwoTwoStrings
{
TwoStrings s21;
TwoStrings s22;
};
|
|
Assignment Operator¶
Second way of copying objects: overwrite an existing object
class point
{
// ...
};
point p1, p2;
// ...
p2 = p1; // assignment!
|
|
But …
As with the copy constructor ⟶ pointer members!
Assignment operator is best self defined when pointer members are involved
Assignment Operator and Pointer Members: Memory Leak¶
Caution, naively buggy!
String& String::operator=(
const String& s)
{
_c_str = new char[
strlen(s._c_str)+1];
strcpy(_c_str, s._c_str);
return *this;
}
String s1("hello");
String s2("hallo");
s2 = s1; // LEAK!
|
Assignment Operator and Pointer Members: Memory Leak, Straighforward Fix¶
Caution, still naively buggy!
String& String::operator=(
const String& s)
{
delete[] _c_str; // BUG!!
_c_str = new char[
strlen(s._c_str)+1];
strcpy(_c_str, s._c_str);
return *this;
}
WTF, why could this be a bug??
Assignment Operator and Pointer Members: Self-Assignment¶
Correct nonsense …
Why would somebody want to write this?
But anyway, it is legal!
int i = 42;
i = i;
|
String s("hello");
s = s; // SEGFAULT!! (if you're lucky)
|
Self Assignment
Rare but true!
User expects that this is not an error
Assignment Operator: Self Assignment, Correctly Implemented¶
Ultimate Fix: Self Assignment Check
String& String::operator=(
const String& s)
{
if (this != &s)} { // SELF ASSIGNMENT CHECK!!
delete[] _c_str;
_c_str = new char[
strlen(s._c_str)+1];
strcpy(_c_str, s._c_str);
}
return *this;
}