C + + classes and objects (inheritance)

Posted by mohvmark on Fri, 31 Dec 2021 07:07:16 +0100

  • I hope you don't deliberately live in pursuit of a number. I hope you find the real value
  • You must insist on being yourself, calm down and do what you like, and then give yourself to fate

inherit

Basic syntax of inheritance

  • When defining these classes, the members of the lower level have their own characteristics in addition to the commonalities of the upper level.
  • Benefits of inheritance: you can reduce duplicate code
class A : public B; 

Class A is called a subclass or derived class
Class B is called a parent or base class

//Public page
class BasePage
{
public:
	void header()
	{
		cout << "Home page, open class, login, registration...(Common head)" << endl;
	}

	void footer()
	{
		cout << "Help center, communication and cooperation, station map...(Common bottom)" << endl;
	}
	void left()
	{
		cout << "Java,Python,C++...(Public classification list)" << endl;
	}

};

//Java page
class Java : public BasePage
{
public:
	void content()
	{
		cout << "JAVA Subject video" << endl;
	}
};
//Python page
class Python : public BasePage
{
public:
	void content()
	{
		cout << "Python Subject video" << endl;
	}
};
//C + + page
class CPP : public BasePage
{
public:
	void content()
	{
		cout << "C++Subject video" << endl;
	}
};

void test01()
{
	//Java page
	cout << "Java The download video page is as follows: " << endl;
	Java ja;
	ja.header();
	ja.footer();
	ja.left();
	ja.content();
	cout << "--------------------" << endl;

	//Python page
	cout << "Python The download video page is as follows: " << endl;
	Python py;
	py.header();
	py.footer();
	py.left();
	py.content();
	cout << "--------------------" << endl;

	//C + + page
	cout << "C++The download video page is as follows: " << endl;
	CPP cp;
	cp.header();
	cp.footer();
	cp.left();
	cp.content();


}

int main() {

	test01();

	system("pause");

	return 0;
}

Members in derived classes consist of two parts:

One class is inherited from the base class, and the other is a member added by itself.

Inherited from the base class shows its commonness, while the new members reflect its individuality.

Inheritance mode

Inheritance syntax: class subclass: inheritance method parent class

There are three inheritance methods:

  • Public inheritance
  • Protect inheritance
  • Private inheritance

The key is to understand the following pictures:

class Base1
{
public: 
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};

//Public inheritance
class Son1 :public Base1
{
public:
	void func()
	{
		m_A; //Access to public permissions
		m_B; //Access protected permissions
		//m_C; // Inaccessible
	}
};

void myClass()
{
	Son1 s1;
	s1.m_A; //Other classes can only access public permissions
}

//Protect inheritance
class Base2
{
public:
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};
class Son2:protected Base2
{
public:
	void func()
	{
		m_A; //Access protected permissions
		m_B; //Access protected permissions
		//m_C; // Inaccessible
	}
};
void myClass2()
{
	Son2 s;
	//s.m_A; // Inaccessible
}

//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; //Access to private rights
		m_B; //Access to private rights
		//m_C; // Inaccessible
	}
};
class GrandSon3 :public Son3
{
public:
	void func()
	{
		//Son3 is a private inheritance, so the properties of inherited son3 cannot be accessed in GrandSon3
		//m_A;
		//m_B;
		//m_C;
	}
};

Object model in inheritance

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

Use the development tool to view the attribute distribution map in the class:
Enter the command: cl /d1 reportSingleClassLayout to view the file name of the class name

Construction and deconstruction order in inheritance

  • After a subclass inherits from the parent class, when a subclass object is created, the constructor of the parent class will also be called
  • Question: which is the construction and deconstruction order of parent and child classes?

Example:

class Base 
{
public:
	Base()
	{
		cout << "Base Constructor!" << endl;
	}
	~Base()
	{
		cout << "Base Destructor!" << endl;
	}
};

class Son : public Base
{
public:
	Son()
	{
		cout << "Son Constructor!" << endl;
	}
	~Son()
	{
		cout << "Son Destructor!" << endl;
	}

};


void test01()
{
	//In inheritance, the constructor of the parent class is called first, and then the constructor of the child class is called. The deconstruction order is opposite to that of the construction
	Son s;
}

int main() {

	test01();

	system("pause");

	return 0;
}

Summary: in inheritance, the constructor of the parent class is called first, and then the constructor of the child class is called. The deconstruction order is opposite to that of the construction

Writing about inheritance and multiple classes

  • Inheritance: class Son2:protected Base2 syntax: class subclass: inheritance method parent class
  • Multiple classes: Circle:: setr (int r) the syntax here represents the scope of the member function

Inherit the handling of members with the same name

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

  • Members with the same name of the subclass can be accessed directly
  • Scope is required to access the member with the same name as the parent class

Example:

class Base {
public:
	Base()
	{
		m_A = 100;
	}

	void func()
	{
		cout << "Base - func()call" << endl;
	}

	void func(int a)
	{
		cout << "Base - func(int a)call" << endl;
	}

public:
	int m_A;
};


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

	//When a subclass has a member function with the same name as the parent class, the subclass will hide all versions of the member function with the same name in the parent class
	//If you want to access a member function with the same name hidden in the parent class, you need to add the scope of the parent class
	void func()
	{
		cout << "Son - func()call" << endl;
	}
public:
	int m_A;
};

void test01()
{
	Son s;

	cout << "Son Lower m_A = " << s.m_A << endl;
	cout << "Base Lower m_A = " << s.Base::m_A << endl;

	s.func();
	s.Base::func();
	s.Base::func(10);

}
int main() {

	test01();

	system("pause");
	return EXIT_SUCCESS;
}

Summary:

  1. Subclass objects can directly access members with the same name in subclasses
  2. The subclass object plus scope can access the member with the same name as the parent class
  3. When a subclass has a member function with the same name as the parent class, the subclass will hide the member function with the same name in the parent class, and the scope can access the function with the same name in the parent class

be careful:

  • If a member function with the same name as the parent class appears in the subclass, the member with the same name in the subclass will hide all member functions with the same name in the parent class
  • If you want to access a member function with the same name hidden in the parent class, you need to add a scope

Inherit static member handling with the same name

Question: how do static members with the same name in inheritance access on subclass objects?

Static members and non static members have the same name and are handled in the same way

  • Members with the same name of the subclass can be accessed directly
  • Scope is required to access the member with the same name as the parent class

Example:

class Base {
public:
	static void func()
	{
		cout << "Base - static void func()" << endl;
	}
	static void func(int a)
	{
		cout << "Base - static void func(int a)" << endl;
	}

	static int m_A;
};

int Base::m_A = 100;

class Son : public Base {
public:
	static void func()
	{
		cout << "Son - static void func()" << endl;
	}
	static int m_A;
};

int Son::m_A = 200;

//Member property with the same name
void test01()
{
	//Access by object
	cout << "Access via object: " << endl;
	Son s;
	cout << "Son  lower m_A = " << s.m_A << endl;
	cout << "Base lower m_A = " << s.Base::m_A << endl;

	//Access by class name
	cout << "Access by class name: " << endl;
	cout << "Son  lower m_A = " << Son::m_A << endl;
	cout << "Base lower m_A = " << Son::Base::m_A << endl;
}

//Member function with the same name
void test02()
{
	//Access by object
	cout << "Access via object: " << endl;
	Son s;
	s.func();
	s.Base::func();

	cout << "Access by class name: " << endl;
	Son::func();
	Son::Base::func();
	//In case of the same name, the subclass will hide all member functions with the same name in the parent class and need to add scope access
	Son::Base::func(100);
}
int main() {

	//test01();
	test02();

	system("pause");

	return 0;
}

Summary: static members with the same name are handled in the same way as non static members, except that they can be accessed in two ways (through object and class names)

be careful:

  • Static member variables: declared within the class, initialized outside the class
  • That is, there are two ways to access static member variables: ① through the object son s; s.m_ A ; ② By class name son:: M_ A ;
  • Static member variable features: all objects share the same data, memory allocation, in class declaration and out of class initialization in the compilation stage
  • Static member function features: all objects share the same data and can only access static member variables
  • If a subclass has a static member function with the same name as the parent class, it will also hide all member functions with the same name in the parent class. If you want to access the hidden member with the same name in the parent class, you need to add a scope

Multiple inheritance syntax

  • C + + allows a class to inherit multiple classes. In short, a class can have multiple fathers

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, and the scope area needs to be added. Therefore, multiple inheritance is not recommended in the actual development of C + +

Example:

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

class Base2 {
public:
	Base2()
	{
		m_A = 200;  //Start with m_B will not be a problem, but changing to mA will cause ambiguity
	}
public:
	int m_A;
};

//Syntax: class subclass: inheritance method parent class 1, inheritance method parent class 2 
class Son : public Base2, public Base1 
{
public:
	Son()
	{
		m_C = 300;
		m_D = 400;
	}
public:
	int m_C;
	int m_D;
};


//Multi inheritance can easily lead to the situation of members with the same name
//By using the class name scope, you can distinguish which members of the base class are called
void test01()
{
	Son s;
	cout << "sizeof Son = " << sizeof(s) << endl;
	cout << s.Base1::m_A << endl;
	cout << s.Base2::m_A << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}

Summary: in multi inheritance, if the parent class has the same name, the scope should be added when the child class is used

diamond inheritance

Diamond inheritance concept:

  • Two derived classes inherit the same base class

  • Another class inherits two derived classes at the same time

  • This inheritance is called diamond inheritance, or diamond inheritance

            ________
            | A class |
            |______|
           /        \
          /           \
      ________        ________
      | B class |        |  C class |
      |______|        |______|
          \               /
            \  ________ /
              | D  class  |   
              |________|

Syntax: class sheet: virtual public animal {};

class Animal
{
public:
	int m_Age;
};

//After adding the virtual keyword before inheritance, it becomes virtual inheritance
//At this time, the public parent class Animal is called the virtual base class
class Sheep : virtual public Animal {};
class Tuo   : virtual public Animal {};
class SheepTuo : public Sheep, public Tuo {};

void test01()
{
	SheepTuo st;
	st.Sheep::m_Age = 100;
	st.Tuo::m_Age = 200;

	cout << "st.Sheep::m_Age = " << st.Sheep::m_Age << endl;
	cout << "st.Tuo::m_Age = " <<  st.Tuo::m_Age << endl;
	cout << "st.m_Age = " << st.m_Age << endl;
}


int main() {

	test01();

	system("pause");

	return 0;
}

Summary:

  • The main problem caused by diamond inheritance is that subclasses inherit two copies of the same data, resulting in waste of resources and meaninglessness
  • Using virtual inheritance can solve the problem of diamond inheritance

Implementation principle of internal bottom layer:

  • Point to the internal virtual base class table (record offset data in the table) (the last two point to the same data)

Reference link 16:20

Topics: Class Polymorphism