C ++ primer Reading Notes 10-Inheritance
Encapsulation, inheritance, and polymorphism are the three basic concepts of C ++. Here we will summarize the inheritance-related things.
Class 1 derived list
The class derivation List specifies the base class to be inherited by the derived class. One or more base classes in the derived list are as follows:
Class B: public A1, protected A2, private A3
However, single inheritance is the most common and many inheritance is rare.
2. Definition of a derived class
When a derived class is inherited, it contains all the members of the parent class, even if the private member cannot be accessed. The virtual function in the parent class must be defined in the derived class, as shown in figure
If this parameter is not specified, the derived class inherits the virtual functions of the base class.
3. The base class must be defined.
A declared class cannot appear in the derived class list of a derived class. Therefore, the derived class is likely to access the list of base classes, but if the base class does not
Is defined, so it is wrong to do so.
4. Declaration of a derived class
The list of derived classes cannot appear in the list of derived classes, for example:
Class B: public A; // error
The correct statement should be:
Class B;
Class;
5. Inheritance Modifier
There are three inheritance methods in C ++: public, protected, and private (3 p for short ). Regardless of the Inheritance Method, the private member in the base class
Cannot be accessed by derived user code or member definition code. The following describes three inheritance methods:
<1> private inheritance: all the members of the base class are private members in the derived class, but the private Members of the base class cannot be accessed.
<2> protected inheritance: the public and protected members of the base class become the protected members of the subclass. The private Members of the base class are still inaccessible.
<3> public inheritance: the public of the base class is changed to the public of the derived class, and the protected is changed to the protected of the derived class. The private of the base class cannot be accessed.
6 protected Modifier
When protected modifies a class member, the class member can be defined by the class member but cannot be used by the user code. This is similar to private
Secondly, the protected modifier can be accessed by the quilt class, which is similar to public but not private.
7. Non-inherited members
Constructor, replication control member (copy constructor, value assignment operator, destructor) This is a function that cannot be inherited
8. constructor of the derived class
General format of the derived class constructor:
DeriveClass (xxx): baseClass (xxx), x1 (x), x2 (x )....
<1> In addition to initializing the newly defined members, the constructor of the derived class also initializes the members of the base class. The sequence is to first call the constructor of the base class to initialize the members of the base class, then Initialize New members (the order is the Declaration Order)
<2> if you do not have a self-defined constructor, the compiler combines the constructor into a default constructor, first calls the default constructor of the base class, and then initializes other new members.
<3> Note: if the base class does not have a default constructor, the compiler cannot synthesize the default constructor. If the default constructor of the derived class is not defined at this time, in this case, an error occurs. For example, -- "error C2512:" Derive ": no suitable default constructor is available ."
<4> if you do not specify the base class constructor in the initialization list of the derived class constructor, the default constructor of the base class is called.
<5> the default real-parameter derived class of the derived class constructor can set all parameters of the constructor as default parameters, and 0-N default parameters can be used.
9 replication control in a derived class
Replication control includes the copy constructor, value assignment operator, and destructor.
<1> if no replication constructor is defined, the compiler will synthesize a replication constructor, which calls the replication constructor of the base class.
<2> A custom replication constructor generally calls the replication constructor of the base class. Otherwise, an exception occurs.
<3> if no value assignment operator is defined, a value assignment operator is automatically merged during compilation, which calls the copy operator of the base class.
<4> do not assign values to custom value assignment operators.
Derive& Derived::operator =(Derived& rh){if(this != &rh){Base::operator=(rh);//do whatever needed to clean up the old value//assign the members from the derived}}
The reason for doing so is to prevent the assignment by ourselves. When assigning values by ourselves, we usually need to clear the dynamically opened memory first. if we do not add the if (this! = & Rh), then when you assign a value to yourself, you will discard yourself (clear yourself ).
<5> destructor of the derived class
This is different from the first two. The destructor of the derived class is only responsible for the structure of the newly defined object, and not for the analysis of the base class object. When the object destructor of a derived class is used, the compiler first calls its own destructor and then calls the destructor of the base class. Each class, regardless of the base class or derived class, is only responsible for clearing its own members.
The preceding example code is as follows:
# Pragma once # include
Using namespace std; class Base {public: Base () {m = 10; cout <"Base default constructor" <
M = base. m; cout <"the base operator =" <
Execution result:
Base default constructor
This is the separtor -----------------
The base copy constructor
The base operator =
Derived destructor
Base destructor
Derived destructor
Base destructor
10 call a function of a derived class
In the case of inheritance, the scope of the derived class is nested in the scope of the base class. If the name cannot be determined in the derived class, the definition of Zhao's name will be defined in the peripheral base class.
<1> the principle of calling a function in a derived class is as follows: first, search for the name in the derived class and then stop it. If not, search for the name in the base class.
<2> static and dynamic types
Static type: it refers to the expression type that is determined only by analyzing the program text without considering the execution semantics of the expression. The static type only depends on the form of the program text containing the expression, but does not change when the program is running.
Dynamic type: the type of the final derived object referenced by the Left value represented by an left value expression. The dynamic type of a right-value expression is its static type.
<3> the static type of the object, referenced or pointer determines the behavior that the object can execute.
Therefore, the referenced or pointer cannot execute the newly defined member name in the derived class.
<4> the name of the base class conflicts with that of the derived class.
When the base class has the same name as the derived class, the derived class will block members with the same name in the base class. If you want to call a Base class member, you must call it explicitly, for example, Base: func ();
<5> block base class member functions
The base class and the derived class have the same name function, but the prototype is not the same (parameter), then the derived class cannot directly call the function with the same name as the base class. Based on the previous principles, if you find the same name, you will not find the base class, so the following program is wrong.
class A{public:void fun(){};}class B : public A{public:void fun(int){};private int x;}B b;b.fun(11); //OKb.func(); //error
11 using
You can use using in a derived class to change the level of the member inherited from the base class, provided that the derived class has access permissions to the member of the base class.
//Base.h#pragma once#include
using namespace std;class Base{public:Base(void){ n = 100; };~Base(void){};size_t size()const{return n;}protected://private:size_t n;int fn(int x){return x;};int fn(){return 11;}};
//Derived.h#pragma once#include "base.h"class Derived :private Base{public:Derived(void){};~Derived(void){};using Base::size;using Base::fn;};
// Main. cpp # include "Base. h" # include "Derived. h" # include
Using namespace std; void main () {Derived XX; Base YY; cout <
Here we can also see that if the Base class function has a heavy load, for the same using Base: XXX, the base class function named XXX can be declared in the derived class. It can be described as one declaration and multiple uses.
12 relationship between friend and inheritance
Youyuan has nothing to do with inheritance. The derived class of the base class cannot be accessed by the derived class of the base class. The derived class of the youyuan class has no access permission to the base class.
13 reference conversion, conversion object
Reference conversion: convert a derived class object to a reference of the base class type
Conversion object: convert a derived class object to a base class object. The parameters are fixed at this time, and the objects during compilation and running are base class objects. The base class of the derived class is copied to the form parameter.
Reference conversion: converts a derived class object to a reference of the base class. However, if the value is assigned, the base class part of the derived class is assigned to the Base class object, which is the same as the slicing effect of the pointer.
14 conversion between the base class and the derived class
The conversion from a derived class to an object to a base class is also conditional. This condition is that the derived class is inherited through public, so that it can be implemented in both the Member Code and the user code.
Derived d;Base b = d;
If it is inherited through protected, this code can only be used in the member definition.
15 default inheritance criteria
Classes and struct have the opposite inheritance criteria by default.
<1> if no qualifier is added for class inheritance, private inheritance is used by default. If the struct does not have a qualifier, the default public inheritance is used.
<2> In addition, the default value between the first qualifier in strut from definition to internal is public modifier, but the default value of class is private modifier.