Copy constructor of C + + (copy constructor)

Posted by bnownlater on Fri, 26 Jun 2020 07:54:49 +0200

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

Topics: network