C + + Basics - overloaded assignment operator '=‘

Posted by scm24 on Mon, 21 Feb 2022 14:53:57 +0100

Why should the assignment operator '=' be overloaded

  • In some cases, when we write a class, we do not need to overload the "=" operator for the class, because the compilation system provides the default assignment operator "=" for each class. When using this default assignment operator to operate class objects, the operator will assign all data members of the class once.
  • When the program does not explicitly provide an assignment operator overloaded function with this class or its reference as a parameter, the compiler will automatically generate such a default assignment operator overloaded function.
  • For example, there are the following categories:

boy.h

#pragma once
#include <string>
using namespace std;

class Boy{
public:
	Boy(const char* name = "unknown", int age = 0, int salary = 0);
	~Boy();

	//Assignment operator overload defined
	Boy& operator=(const Boy& boy);
	string description() const;
private: 
	char* name;	//full name
	int age;	//Age
	int salary;	//salary
};

boy.cpp

#include <iostream>
#include <sstream>

#include "Boy.h"


Boy::Boy(const char* name, int age, int salary){
    if (!name) {
        name = (char*)"Unnamed";
    }
    this->name = new char[sizeof(name)];
    strcpy_s(this->name, sizeof(name), name);

    this->age = age;
    this->salary = salary;
}

Boy::~Boy(){
    if (name) {
        delete name;
        name = NULL;
    }
}

Boy& Boy::operator=(const Boy& boy){
    if (name) {		//If the name of the current object is not empty
        delete name;	//Free memory
        name = NULL;	//Point to null
    }
	
	//Reassign a boy Name size memory
    this->name = new char[strlen(boy.name) + 1];
    strcpy_s(this->name, strlen(boy.name) + 1, boy.name);

    this->age = boy.age;
    this->salary = boy.salary;
    return *this;	//Returns a reference to the current object
}

string Boy::description() const{
    stringstream ret;
    ret << "full name:" << name << "\t Age:" << age << "\t salary:" << salary;
    return ret.str();
}

main.cpp

#include <iostream>
#include <Windows.h>
#include "Boy.h"
using namespace std;

int main(void) {
	Boy boy1("Zhang San", 18, 10000);
	Boy boy2;
	Boy boy3;

	//Call the assignment operator Boy & operator = (const Boy & boy);
	boy3 = boy2 = boy1;

	cout << boy1.description() << endl;
	cout << boy2.description() << endl;
	cout << boy3.description() << endl;

	system("pause");
	return 0;
}

Summary:

  • In general, the parameter of the overloaded function of the assignment operator is the reference of the const type of the class in which the function is located

  • const is added because:
    ① We don't want to make any changes to the "original" used for assignment in this function.
    ② With const, the function can accept const and non const arguments; If not, only non const arguments can be accepted.

  • Reference is used because:
    This can avoid one copy of the arguments during function call and improve the efficiency.

  • be careful:
    The above provisions are not mandatory. const or reference may not be added, and even the parameter may not be the object of the function.

The return value is the reference of the assignee, * this,

  • as a result of
    ① This avoids one copy when the function returns and improves the efficiency.
    ② More importantly, this can realize continuous assignment, that is, similar to a=b=c. If you return the value type instead of the reference, when a=b is executed, call the assignment operator to overload the function. When the function returns, because it returns the value type, you need to copy the "thing" behind the return to get an unnamed copy (some materials call it "anonymous object"), and then return this copy, This copy is an R-value, so after executing a=b, you get an R-value, and then executing = c will make an error.

  • be careful:
    This is not mandatory. We can declare the return value of the function as void and then return nothing, but we can't assign values continuously.

Topics: C++ Back-end