Copy constructor (copy constructor)
1, Copy constructor concept
Copy constructor is a special kind of constructor. When creating an object, it uses the previously created object in the same class to initialize the newly created object. Copy constructors are commonly used for:
Initialize the newly created object by using another object of the same type.
The copy object passes it as an argument to the function.
Copy the object and return it from the function.
2, An example
1. First question
Requirement Description:
Customize the string class to simplify string operations
//MyString.h class String{ public: String(char * str = ""); friend ostream & operator<<(ostream & os, const String & str); String & operator=(String & str); virtual ~String(); private: int length; //The actual length of the string (excluding \ 0) char * value; //An array of characters that are actually stored }
//main.cpp String str1 = "Love Coke"; String str2; str2=st1;
be careful:
If we do not overload the assignment operator, the contents of the object str1 will be copied directly to the new object str2, which is enough for a simple class without a pointer, but when we have a pointer as a data member, byte by byte copying will copy the pointer from one object to another, and two pointers will point to a memory at the same time
Solution:
Overloaded assignment operator
(students who don't know how to overload operators can see: Operator overloading in C + +)
String & String::operator=(String & str){ delete[] value; //First release the default space of the string length = strlen(str.value); //Remeasure string length value = new char[lengh + 1]; strcpy(value,str.value); return *this; }
be careful:
1. When overloading assignment operators, make sure that all data members in one object are copied to another.
2. If you have more than one data member, each member needs to be copied to the target object.
2. Another scenario
When an object of the same class initializes another object
Sting str1("Love Coke"); String str2(str1);
Solution:
Define an assign / copy constructor for a class (that is, an object-based constructor) General format: XXX::XXX(XXX & xxxptr) The const keyword can ensure that the copied objects will not be changed during the copying process: XXX::XX(const XXX & XXXPtr)
The copy constructor (copy constructor) is called in three scenarios:
1. When an object of a class is initialized to another object of the same class
2. When an object is passed as an argument to a function
3. When the function returns an object
3, Specific examples
Customize the string class to simplify string operations
Specific implementation:
MyString.h
#ifndef MYSTRING_H #define MYSTRING_H #include<iostream> #include<cstring> using namespace std; //Custom string wrapper class class MYString { public: MYString(); MYString(char * str); MYString(const MYString & str);//Copy construct / copy construct virtual ~MYString(); //Overloads the assignment operator to copy every element of the array instead of just the array pointer const MYString & operator=(const MYString & str); friend ostream & operator<<(ostream & out, const MYString & str); protected: private: int m_length; //Actual length of string - excluding \ 0 char * m_value; //Array of characters that actually store characters }; #endif // MYSTRING_H
MySting.cpp
#include "MYString.h" #include<cstdio> MYString::MYString() : m_length(0) { //char * str = "; / / the length is 0, but there will be unique elements in the actual character array:, 0 this->m_value = new char[1]; this->m_value[0] = '\0'; } MYString::MYString(char * str) { //Assign the value of the passed in string str to m in the current object_ value if(NULL==str) { this->m_value = new char[1]; this->m_value[0] = '\0'; return; } m_length = strlen(str); m_value = new char[m_length + 1];//Make room for \ 0 strcpy(m_value ,str); } MYString::MYString(const MYString & str) { m_length = strlen(str.m_value); m_value = new char[m_length + 1]; strcpy(m_value,str.m_value); } ostream & operator<<(ostream & out , const MYString & str) { out<<str.m_value<<"\n"; //out<<"m_ Length of value: "< strlen (str.m_ value); printf("%p",str.m_value); return out; } //When overloading assignment operators, make sure that all data from one object is copied to another (especially if there are pointers) //If there are multiple members, each member needs to be copied to the memory object - deep copy //If a class has pointer type members, in most cases, you need to use deep copy to copy the contents pointed by the pointer, so that the original object and the new object are independent of each other //If a member of a class does not have a pointer, shallow copy is sufficient const MYString & MYString::operator=(const MYString & str) { if(this == &str) return *this; delete[] m_value; //First, release the original space of the string m_length = str.m_length; m_value = new char[m_length + 1]; strcpy(m_value,str.m_value); return *this; } MYString::~MYString() { //When decomposing, free the space pointed by the character array delete[] m_value; }
main.cpp
#include<iostream> #include"MYString.h" using namespace std; void TestString(); int main() { TestString(); return 0; } void TestString() { MYString str1("abc"); MYString str2 = "abcdefg"; cout<<str1<<endl; cout<<str2<<endl; cout<<""<<endl; cout<<"Assignment between objects:"<<endl; str1= str2; cout<<str1<<endl; cout<<str2<<endl; MYString str3("Love Coke"); MYString str4(str3); cout<<str3<<endl; cout<<str4<<endl; } //Print results: /** abc 00CE1248 abcdefg 00CE11A8 Assignment between objects: abcdefg 00CE10F8 abcdefg 00CE11A8 Love Coke 00CE0E28 Love Coke 00CE0E40 */
4, Summary
Assignment / copy constructor
For simple classes, the default copy constructor is generally sufficient, and there is no need to explicitly define a function similar constructor.
When a class has other resources, such as dynamically allocating memory, opening files, pointers to other data, network connections, etc., the default copy constructor cannot copy these resources. The copy constructor must be explicitly defined to copy all the data of the object