[C++] Basic features of inheritance (definition, assignment conversion, friends, static members, virtual inheritance, default member functions, scope)


1. The definition of inheritance

It allows programmers to extend and add functions while maintaining the characteristics of the original class, thus generating a new class, called a derived class.

1. Define the format

Insert image description here
Person is the parent class, also called the base class. Student is a subclass, also called a derived class

2. Changes in access methods of inherited base class members

Insert image description here
Summarize:

  1. Base class private members are not visible in derived classes no matter how they are inherited . Invisible here means that the private members of the base class are still inherited into the derived class object, but the syntax restricts the derived class object from accessing it whether inside or outside the class.
    Insert image description here

  2. Private members of the base class cannot be accessed in the derived class. If the base class member does not want to be accessed directly outside the class, but needs to be accessible in the derived class, it is defined as protected . It can be seen that the protected member qualifier is due to inheritance.

  3. The private members of the base class are not visible in the subclass. The access method of other members of the base class in the subclass == Min (member's access qualifier in the base class, inheritance method), public > protected > private.

  4. The default inheritance method when using the keyword class is private , and the default inheritance method when using struct is public , but it is best to write the inheritance method explicitly.

  5. In actual applications, public inheritance is generally used, protected/private inheritance is rarely used, and protected/private inheritance is not recommended.

2. Assignment and conversion of base class and derived class objects

1. Derived class objects can be assigned to base class objects/base class pointers/base class references. There is a vivid term here called slicing or cutting. It means cutting off the parent class part of the derived class and assigning it to it.
2. Base class objects cannot be assigned to derived class objects.
Insert image description here
Insert image description here

3. Scope of inheritance

1. In the inheritance system, base classes and derived classes have independent scopes.

2. There are members with the same name in the subclass and parent class

If there are members with the same name in the subclass and the parent class, the subclass members will block the parent class from direct access to the members with the same name. This situation is called hiding, also called redefinition. (In subclass member functions, you can use base class::base class members for explicit access)
Insert image description here

3. Hiding of member functions

It should be noted that if it is the hiding of a member function, only the function names need to be the same to constitute hiding.
Insert image description here

4. Note that in practice it is best not to define members with the same name in the inheritance system.

4. Default member functions of derived classes

Base class (parent class):

class Person {
    
    
public:
	Person(const char*name)
		:_name(name)
	{
    
    
		cout << "Person()" << endl;
	}
	Person(const Person& p)
		:_name(p._name)
	{
    
    
		cout << "Person(const Person&p)" << endl;
	}
 
	Person& operator=(const Person& p) {
    
    
		cout << "Person operator=(const Person& p)" << endl;
		if (this != &p) {
    
    
			_name = p._name;
		}
		return *this;
	}

	~Person() {
    
    
		cout << "~Person()" << endl;
	}
protected:
	string _name;
};

Derived classes (subclasses)

class Student :public Person {
    
    
public:
	Student(const char*name="张三", int id = 0)
		//派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。
		:Person(name)
		,_id(id)
	{
    
    }

	Student(const Student& s) 
		// 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
		:Person(s)//切割
		,_id(s._id)
	{
    
    }

	Student& operator=(const Student& s) {
    
    
		//派生类的operator = 必须要调用基类的operator = 完成基类的复制
		if (this != &s) {
    
    
			Person::operator=(s);//发生切割
			_id = s._id;
		}
		return *this;
	}
		~Student()
	{
    
    
		// 析构函数的函数名被
		// 特殊处理了,统一处理成destructor

		// 显示调用父类析构,无法保证先子后父
		// 所以子类析构函数完成就,自动调用父类析构,这样就保证了先子后父
		 
		//析构函数:先析构子类后析构父类
		//构造函数:先构造父类后构造子类
	}

protected:
	int _id;
};

Running results:
Insert image description here
Summary:

  1. The constructor of the derived class must call the constructor of the base class to initialize that part of the members of the base class. If the base class does not have a default constructor , it must be called explicitly during the initialization list phase of the derived class constructor.
  2. The copy constructor of the derived class must call the copy constructor of the base class to complete the copy initialization of the base class.
  3. The operator of the derived class must call the operator of the base class to complete the copy of the base class.
  4. The destructor of the derived class will automatically call the destructor of the base class to clean up the base class members after being called. Because this can
    ensure that the derived class object cleans up the derived class members first and then the base class members.
  5. When initializing a derived class object, the base class constructor is called first and then the derived class constructor is called.
  6. To clean up the destructor of derived class objects , first call the destructor of the derived class and then call the destructor of the base class.

Insert image description here

5. Inheritance and friendship

Friend relationships cannot be inherited, which means that base class friends cannot access private and protected members of subclasses.
Insert image description here
For normal operation, derived classes must also add friends.

6. Inheritance and static members

If the base class defines static members, there will be only one such member in the entire inheritance system. No matter how many subclasses are derived, there is only one static member instance.

Insert image description here

7. Diamond virtual inheritance

1. Diamond Inheritance

Insert image description here
The problem of diamond inheritance: From the following object member model construction, it can be seen that diamond inheritance has data redundancy and ambiguity problems. There will be two copies of the Person member in the Assistant object.
Insert image description here

2. Virtual inheritance

Virtual inheritance can solve the ambiguity and data redundancy problems of diamond inheritance. As shown in the inheritance relationship above, using virtual inheritance when Student and Teacher inherit Person can solve the problem. It should be noted that virtual inheritance should not be used elsewhere.
Insert image description here

3. Diamond virtual inheritance principle:

class A
{
    
    
public:
 int _a;
};
// class B : public A
class B : virtual public A
{
    
    
public:
 int _b;
};
// class C : public A
class C : virtual public A
{
    
    
public:
 int _c;
};
class D : public B, public C
{
    
    
public:
 int _d;
};
int main()
{
    
    
 D d;
 d.B::_a = 1;
 d.C::_a = 2;
 d._b = 3;
 d._c = 4;
 d._d = 5;
 return 0;
}

1. Memory distribution of diamond inheritance

The following figure is the memory object member model of diamond inheritance: here you can see data redundancy
Insert image description here

2. Virtual inheritance memory distribution

The following figure is the memory object member model of diamond virtual inheritance: here we can analyze that in the D object, A is placed at the bottom of the object composition. This A belongs to both B and C. So how do B and C find the common A? ? Here is a table pointed to by two pointers of B and C. These two pointers are called virtual base table pointers, and these two tables are called virtual base tables. The offset stored in the virtual base table. A below can be found by the offset.
Insert image description here
Insert image description here
Insert image description here

Guess you like

Origin blog.csdn.net/m0_74774759/article/details/132104793