C + + learning diary - operator overloading and inheritance

Posted by skizzay on Thu, 20 Jan 2022 12:44:34 +0100

1, Greater than operator overload

#include <iostream>
using namespace std;

class Student
{
public:
    Student(string n, int i, float s)
    {
        this->id = i;
        this->name = n;
        this->scored = s;
    }
    bool operator>(Student &s)
    {
        if (this->scored > s.scored)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

private:
    string name;
    int id;
    float scored;
};

int main()
{
    Student s1("bb", 10, 99);
    Student s2("cb", 0, 59);

    if (s1 > s2)
    {
        cout << "bb six" << endl;
    }
    else
    {
        cout << "cb six" << endl;
    }

    return 0;
}

2, Relational operator overloading

#include <iostream>
using namespace std;

class Person
{
public:
    Person(string name, int age)
    {
        this->m_name = name;
        this->m_age = age;
    }
    int m_age;
    string m_name;

    bool operator==(Person &p)
    {
        if (this->m_name == p.m_name && this->m_age == p.m_age)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    bool operator!=(Person &p)
    {
        if (this->m_name == p.m_name && this->m_age == p.m_age)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
};

int main()
{
    Person p1("qq", 18);
    Person p2("qq", 18);
    if (p1 == p2)
    {
        cout << "p1=p2" << endl;
    }
    else
    {
        cout << "p1!=p2" << endl;
    }

    if (p1 != p2)
    {
        cout << "p1!=p2" << endl;
    }
    else
    {
        cout << "p1=p2" << endl;
    }
    return 0;
}

3, Assignment operator overload

C + + will add at least four functions to one class:

1 default constructor

2. Default destructor

3. Default copy constructor (copy a value of the attribute, shallow copy)

4. The assignment operator overloads the function operator (copy the value and shallow copy of the attribute),


#include <iostream>
using namespace std;

class Person{
public:
	Person(int age)
	{
		m_Age = new int(age);
	}

	~Person()
	{
		if(m_Age != NULL)
		{
			delete m_Age;
			m_Age = NULL;
		}
	}

	//There is a problem with the = overloaded function provided by the system, so we overload it again.
	Person& operator=(Person &p)
	{
		//m_Age = p.m_Age;  // This is what the compiler does by default. (light copy)
		if(m_Age != NULL)   //Provide your own deep copy.
		{
			delete m_Age;
			m_Age = NULL;
		}

		m_Age = new int(*p.m_Age);

		return *this;
	}

	int *m_Age;
};

int main()
{
	/*
	Person p1("Zhang San ", 18);
	cout << "p1 Name: "< P1. M _name < < age:" < P1. M _age < < endl;
	Person p2 = p1;
	cout << "p2 Name: "< P2. M _name < < age:" < P2. M _age < < endl;
	*/

	Person p3(18);
	Person p4(20);  //Parameterized constructor / / Person p4 = p3// Copy constructor (shallow copy by default), I don't call overloaded functions
	Person p5(30);

	p5 = p4 = p3;        //If there is a concatenation operation, the object is returned by reference.

	cout << "p3 Age of:" << *p3.m_Age << endl;
	cout << "p4 Age of:" << *p4.m_Age << endl;
	cout << "p5 Age of:" << *p5.m_Age << endl;

	return 0;
}

Conclusion:

1. As long as an attribute is opened to the heap, when using an object to assign a value to another object, you must rewrite the overloaded function operate to cast a common deep copy

4, Function call operator overloading

1. The function operator () can also be overloaded

2. Because the method used after overloading is very similar to the call of a function, it is called an imitation function

3. Imitation function has no fixed writing method and is very flexible

#include <iostream>
using namespace std;

//Function call operator overload.
//Design print class.
class Myprint{
public:
	//Overloaded function call operator
	void operator()(string text)
	{
		cout << text << endl;
	}
};

//Design addition class
class Myadd{
public:
	int operator()(int num1,int num2)
	{
		return num1 + num2;
	}
};

void myint02(string text)
{
	cout << text << endl;
}

int main()
{
	//Myprint myint;
	//m.operator()("helloworld");
	//myint("helloworld");  // It is called an imitation function because it is used very much like the call of a function after overloading.   
	//myint02("helloworld");

	Myadd ma;
	//int ret = ma.operator()(10,20);
	//int ret = ma(10,20);
	//cout << "ret = " << ret << endl;  //30

	cout << ma(10,20) << endl;        //30
	cout << Myadd()(10,20) << endl;   //30

	//Myadd() - > unknown function object Myadd()(10,20);
	//Ma - > named function object ma(10,20);

	return 0;
}

5, Inherit

Inheritance is one of the three characteristics of object-oriented.

There are some special relationships between classes,

For example, there is an animal class. Both cats and dogs belong to animals. They have both commonalities and their own individuality.

We found that when defining these classes, the lower level members not only have the commonalities of the upper level, but also have their own characteristics.

At this time, we can consider using inheritance technology to reduce duplicate code.

6, Inherit

Case: for example, we have found that many web pages consist of a public head and a public bottom, but the content of the center is different

A child class is also called a derived class, and a parent class is also called a base class

//Inheritance syntax:

//Class , subclass: inheritance method , parent class

//Benefits of inheritance:

//Reduce duplicate code

#include <iostream>
using namespace std;

//Inheritance -- commonness
class BasePage
{
public:
    void head()
    {
        cout << "Web address, bookmark, search bar, menu bar" << endl;
    }
    void right()
    {
        cout << "Special recommendation" << endl;
    }
    void footer()
    {
        cout << "Comment area and post" << endl;
    }
};

//Inheritance syntax:
//Class subclass: inheritance method parent class

class Page_one : public BasePage
{
public:
    void content()
    {
        cout << "Learn from Yuan Longping" << endl;
    }
};
class Page_two : public BasePage
{
public:
    void content()
    {
        cout << "Never which sweet potato" << endl;
    }
};
class Page_three : public BasePage
{
public:
    void content()
    {
        cout << "Marathon death" << endl;
    }
};

int main()
{
    cout << "Under the first page content map" << endl;
    Page_one po;
    po.head();
    po.right();
    po.content();
    po.footer();
    cout << "The second page is under the content map" << endl;
    Page_two pt;
    pt.head();
    pt.right();
    pt.content();
    pt.footer();
    cout << "The third page is under the content map" << endl;
    Page_three ps;
    ps.head();
    ps.right();
    ps.content();
    ps.footer();

    return 0;
}

7, Inheritance mode

Inheritance syntax:

Class subclass: inheritance method parent class

Inheritance method:

① Public succession

② Protect inheritance

③ Private inheritance

,

#include <iostream>
using namespace std;

//Inheritance mode
//Public inheritance
class Base1{
public:
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};

class Son1:public Base1{   //Public inheritance
public:
	void func()
	{
		m_A = 10;     //Public attribute - > public attribute (public attribute can be accessed in class)
		m_B = 20;     //Protection attribute - > protection attribute (protection attribute can be accessed within the class)
		//m_C = 30;   // Private properties - > not accessible
	}
};

//Protect inheritance
class Base2{
public:
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};

class Son2:protected Base2{  //Protect inheritance
public:
	void func()
	{
		m_A = 100;     //Public attribute - > protection attribute (protection attribute can be accessed within the class)
		m_B = 200;     //Protection attribute - > protection attribute (protection attribute can be accessed within the class)
		//m_C = 300;   // Private properties - > not accessible
	}
};

class GrandSon2:public Son2{
public:
	void func()
	{
		m_A = 50;     //Protection attribute - > protection attribute (protection attribute can be accessed within the class)
		m_B = 50;     //Protection attribute - > protection attribute (protection attribute can be accessed within the class)
	}
};

//Private inheritance
class Base3{
public:
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};

class Son3:private Base3{
public:
	void func()
	{
		m_A = 100;     //Public property - > private property (accessible within the class)
		m_B = 200;     //Protected property - > private property (accessible within the class)
		//m_C = 300;   // Private properties - > not accessible.
	}
};

class GrandSon3:public Son3{
public:
	void func()
	{
		//m_A = 100;     // Private properties - > not accessible
		//m_B = 100;     // Private properties - > not accessible
	}
};

int main()
{
	Son1 s1;
	s1.m_A = 100;       //Public attribute - > public attribute (public attribute can be accessed outside the class)
	//s1.m_B = 200;     // Protection attribute - > protection attribute (protection attribute cannot be accessed outside the class)
	//s1.m_C = 300;     // Private properties - > not accessible
	
	Son2 s2;
	//s2.m_A = 100;     // Public attribute - > protection attribute (protection attribute cannot be accessed outside the class)
	//s2.m_B = 200;     // Protection attribute - > protection attribute (protection attribute cannot be accessed outside the class)
	//s2.m_C = 300;     // Private properties - > not accessible

	Son3 s3;
	//s3.m_A = 100;     // Public attribute - > private attribute (not accessible outside the class)
	//s3.m_B = 200;     // Protected property - > private property (not accessible outside the class)
	//s3.m_C = 300;     // Private properties - > not accessible.

	return 0;
}

8, Symmetry model in inheritance

Question: which members inherit from the parent class belong to the subclass object?
 

#include <iostream>
using namespace std;

class Base
{
public:
    int m_a;

protected:
    int m_b;

private:
    int m_c;
};

class son : public Base
{
public:
    int m_d;
};

int main()
{
    //1. Calculate the size of the parent object
    cout << "sizeof(Base)" << sizeof(Base) << endl;
    //All non static member properties in the parent class will be inherited by the child class.
    //The private member property of the parent class is hidden by the compiler, so it cannot be accessed, but it is inherited
    cout << "sizeof(son)" << sizeof(son) << endl;

    return 0;
}

Conclusion;    

//All non static member properties in the parent class will be inherited by the child class.
/ / the private member attribute of the parent class is hidden by the compiler, so it cannot be accessed, but it is inherited

9, The order of inherited constructors and destructors?

After the child class inherits the parent class. When you create a subclass object,

Father constructs first, subclass constructs again, and deconstruction is the opposite

The order of construction and Deconstruction in inheritance

#include <iostream>
using namespace std;

class Base
{
public:
    Base()
    {
        cout << "Base structure" << endl;
    }
    ~Base()
    {
        cout << "Base Deconstruction" << endl;
    }
};

class Son : public Base
{
public:
    Son()
    {
        cout << "son structure" << endl;
    }
    ~Son()
    {
        cout << "son Deconstruction" << endl;
    }
};
int main()
{
    Base b;
    Son s;

    return 0;
}

10, Handling of members with the same name in inheritance

Question: when a member with the same name appears in the subclass and the parent class, how can I access the data with the same name in the subclass or the parent class through the subclass object

#include <iostream>
using namespace std;

//Handling of members with the same name in inheritance
//1) You can access the member with the same name in the subclass directly.
//2) To access a member with the same name as the parent class, you need to add a scope.

//Design parent class
class Base{
public:
	Base()
	{
		m_A = 10;   //Non static member properties
	}

	void func()     //Non static member function
	{
		cout << "Base - func function call" << endl;
	}

	int m_A;
};

class Son:public Base{
public:
	Son()
	{
		m_A = 20;
	}

	void func()  //Non static member function
	{
		cout << "Son - func function call" << endl;
	}

	int m_A;     //Non static member properties
};

int main()
{
	//1. Processing method of member attribute with the same name.
	//Son s;   // Instantiating an object of a subclass will call the constructor of the parent class first, and then the constructor of the subclass.
	//Cout < < m_a under son = "< S.M_ A << endl;           // Subclass objects can access subclass members directly.
	//Cout < < m_a under base = "" < s.base:: M_ A << endl;    // When a subclass object accesses a parent class member, it needs to be scoped.

	//2. Processing of member functions with the same name.
	Son s;
	s.func();            //If it is called directly, the member with the same name in the subclass is called.
	s.Base::func();      //If the scope is added, the function of the parent class is accessed.

	return 0;
}

Conclusion:

//You can access the member with the same name in the subclass directly,
//To access a member with the same name as the parent class, you need to add a scope

11, Inherits the handling of static members with the same name in.

Question: how do static members with the same name in inheritance access in subclasses

Static member and non static member have the same name. The processing method is consistent

1) You can access static members in subclasses directly

2) Access the static member function in the parent class, and add the scope in front

#include <iostream>
using namespace std;

class Base
{
public:
    static int m_a;
    static void func()
    {
        cout << "base - static void func()" << endl;
    }
};
int Base::m_a = 100;

class Son : public Base
{
public:
    static int m_a;
    static void func()
    {
        cout << "son - static void func()" << endl;
    }
};
int Son::m_a = 200;

int main()
{
    //Calculate the size of subclass objects
    cout << sizeof(Son) << endl;

    //Access by object
    Son s;
    cout << s.m_a << endl;
    cout << s.Base::m_a << endl;
    //Access by class name
    cout << Base::m_a << endl;
    cout << Son::m_a << endl;

    //Access by object
    s.func();
    s.Base::func();
    //Access by class name
    Son::func();
    Base::func();

    Son::Base::func();

    return 0;
}

12, Multi inheritance syntax (not recommended, it may be troublesome and inconvenient to cooperate with others)

In C + +, one class is allowed to inherit multiple classes

Syntax: class subclass: inheritance method parent class 1, inheritance method parent class 2

Multiple inheritance may cause members with the same name to appear in the parent class, which needs to be distinguished by scope

#include <iostream>
using namespace std;

class Base1
{
public:
    Base1()
    {
        m_a = 100;
    }
    int m_a;
};

class Base2
{
public:
    Base2()
    {
        m_a = 200;
    }
    int m_a;
};
//Class subclass: inheritance method parent class 1, inheritance method parent class 2
class Son : public Base1, public Base2
{
public:
    Son()
    {
        m_c = 300;
        m_d = 400;
    }
    int m_c;
    int m_d;
};

int main()
{
    cout << sizeof(Son) << endl;
    //When the names are different, visit the following
    Son s;
    cout << s.Base1::m_a << endl;
    cout << s.Base2::m_a << endl;
    cout << s.m_c << endl;
    cout << s.m_d << endl;
    return 0;
}

Topics: C++