C++ core programming 7 - C++ operator overloading for classes and objects

1. The concept of operator overloading

Operator overloading: redefine an existing operator and give it another function to adapt to different data types

2. Plus operator overloading

Function: add two custom data types (eg. add two persons)

You can overload members of the same class, or between different classes.

For example, it can be operator+(Person &p1, Person &p2), or operator(Person &p1, int number)

Summary 1: It is impossible to change the operator of the expression of the built-in data type (only the custom data type can be overloaded, C++ built-in int, double cannot be overloaded)

Summary 2: Don't abuse operator overloading

3. Left shift operator overloading

Role: output custom data type

#include <iostream>
#include <string>
#include <math.h>
using namespace std;

class Student 
{
public:
    int age;
    long long ID;
};

//左移运算符只能通过全局函数重载
//注意,返回的是ostream &,当返回的是ostream &时,可以在后续调用的时候使用链式编程一直cout,否则单行就只能cout一次
//返回引用,就可以一直对同一个变量进行操作,如果返回的是值不是引用,就会创建一个新的变量
ostream& operator<< (ostream& cout, Student& s1) 
{
    cout << s1.age;
    cout << " ";
    cout << s1.ID;
    return cout;
}

//构造函数调用
void test1()
{
    Student s1;
    s1.age = 25;
    s1.ID = 3220181084;
    cout << s1 << endl;
}

int main()
{
    test1();
    return 0;
}

4. Increment operator overloading

Role: Realize your own integer data by overloading the increment operator

 Assignment: Write an overloaded decrement function

#include <iostream>
#include <string>
#include <math.h>
using namespace std;

class MyInteger
{
    friend ostream& operator<< (ostream& cout, MyInteger m);

public:
    MyInteger()
    {
        Myint = 0;
    }
    //前置--
    //前置--返回引用,返回变量本身
    MyInteger& operator--()
    {
        --Myint;
        return *this;
    }
    //后置--
    //后置--返回值
    MyInteger operator--(int)//后置++和后置--都要新增一个int占位符用来和前置重载函数进行区分
    {
        MyInteger temp = *this;
        Myint--;
        return temp;
    }

private:
    int Myint;
};

ostream& operator<< (ostream& cout, MyInteger m)
{
    cout << m.Myint;
    return cout;
}

void test1()
{
    MyInteger m;
    cout << --m << endl;
    cout << m << endl;
}

void test2()
{
    MyInteger m;
    cout << m-- << endl;
    cout << m << endl;
}

int main()
{
    //test1();
    test2();
    return 0;
}

5. Assignment operator overloading

Case: Create a new pointer variable in the class (created in the heap area, which needs to be released manually by the programmer after the program runs), and use the assignment operation in the test.

1. Use the assignment operator directly (the compiler automatically provides a shallow copy). When we create a destructor in the class and manually release the heap area data, the program will crash. The reason is that the assignment operation automatically provided by the compiler is a shallow copy, and p2 copies the memory address of p1. Therefore, when freeing, the same memory space will be released repeatedly, which will cause errors.

2. Solution: use deep copy to solve the problem. Create a new memory space for p2.

 MyInteger& operator= (MyInteger& m)
    {
        //普通浅拷贝构造函数
        //Myint = m.Myint;
        
        //深拷贝构造函数
        if (Myint != NULL)
        {
            delete Myint;
            Myint = NULL;
        }
        Myint = new int(*m.Myint);
        return *this;
    }

 Conclusion: For variables created in the heap area, you cannot use the assignment operator (shallow copy) generated by the compiler itself, but you need to write a deep copy assignment operator yourself.

 

6. Relational operator overloading

Role: Overload relational operators, allowing two custom type objects to perform comparison operations

7. Function call operator() overloading 

 

#include <iostream>
#include <string>
#include <math.h>
using namespace std;

class MyFunc
{
public:
    int operator()(int num1, int num2)
    {
        return num1 - num2;
    }

};

void test1()
{
    MyFunc myS;
    cout << myS(10, 2) << endl;
    //匿名函数对象,可以不用创建myS对象而直接调用重载函数()
    cout << MyFunc()(10,2) << endl;
}

int main()
{
    test1();
    return 0;
}

Guess you like

Origin blog.csdn.net/MWooooo/article/details/122620815