Summary of C + + inheritance and derivation

1. Basic concepts

Reference resources
Inheritance in C + + is the relationship between classes, for example, a son inherits the property of his father.

Inheritance can be understood as the process of one class getting member variables and member functions from another class. For example, if class B inherits from Class A, then B has member variables and member functions of A.

In C + +, derivation and inheritance is a concept, but from different perspectives. Inheritance is that the son receives the father's property, and derivation is that the father inherits the property to the son.

The inherited class is called parent class or base class, and the inherited class is called child class or derived class.

In addition to the members of the base class, the derived class can also define its own new members to enhance the function of the class.


2. Three inheritance methods of C + +

3. Constructors of C + + base and derived classes

The member function of the base class can be inherited and accessed through the object of the derived class, but this only refers to the ordinary member function, and the constructor of the class cannot be inherited. It makes sense that a constructor cannot be inherited, because even if it is inherited, its name is not the same as the name of a derived class. It cannot be a constructor of a derived class, and certainly not a common member function.

When designing a derived class, the initialization of inherited member variables should also be done by the constructor of the derived class. However, most of the base classes have member variables with private property, which cannot be accessed in the derived class, let alone be initialized by the constructor of the derived class.

This contradiction is universal in the inheritance of C++. The way to solve this problem is to call the constructor of the base class in the constructor of the derived class.

The following example shows how to call the constructor of the base class in the constructor of the derived class.

    1 #include <iostream>
    2 #include <string>
    3 using namespace std;
    4 
    5 //Base class People
    6 class People{
    7 protected:
    8     string m_name;
    9     int m_age;
   10 public:
   11     People(const string&, int);
   12 };
   13 People::People(const string& name, int age): m_name(name), m_age(age){}
   14 
   15 //Derived class Student
   16 class Student: public People{
   17 private:
   18     float m_score;
   19 public:
   20     Student(const string& name, int age, float score);//Parameter constructor of derived class
   21     void display();
   22 };
   23 //People(name, age) is the constructor of the base class
   24 Student::Student(const string& name, int age, float score): People(name, age), m_score(score){}
   25 void Student::display(){
   26     cout << m_name << "The age of:" << m_age << ",The results are:"<< m_score << ". " << endl;
   27     }
   28 int main()
   29 {
   30     Student stu("Xiao Ming", 16, 90.5);
   31     stu.display();
   32     return 0;
   33 }

3.1 call order of constructor

From the above analysis, we can see that the base class constructor is always called first, which means that when creating a derived class object, the base class constructor will be called first, and then the derived class constructor. Constructors are called from the top down, from the base class to the derived class according to the hierarchy of inheritance

3.2 call rules of base class constructor

In fact, when you create an object from a derived class, you must call the constructor of the base class, which is the syntax. In other words, it is better to specify the base class constructor when defining the derived class constructor; if not, call the default constructor of the base class (constructor without parameters); if there is no default constructor, compilation fails.

3.3 key points of derived class constructor

4. actual combat

4.1 source code

    1 #include <iostream>
    2 #include <string>
    3 
    4 using namespace std;
    5 
    6 /**hero.h*/
    7 class Hero
    8 {
    9 private:
   10     string m_NickName;
   11     int m_Level;
   12     int m_MaxLife;
   13     int m_CurrLife;
   14     int x;
   15     int y;
   16 
   17 public:
   18     Hero();
   19 
   20 //  Hero(const string& );
   21 //  Hero(const string&, int);
   22 //  Hero(const string&, int, int, int);
   23     Hero(const string& nickName);
   24     Hero(const string& nickName, int level);//function overloading
   25     Hero(const string& nickName, int level, int maxLife, int currLife);//function overloading
   26 
   27     /** Move method in base class*/
   28     void Move();
   29 
   30     /**Friend function keyword friend,
   31     Defining an operator overload is like defining a function, except that the function name begins with the operator keyword*/
   32     friend ostream& operator<<(ostream& out, Hero& hero);
   33 
   34     /**
   35     About const keyword:
   36     1.Before method: indicates that the return value is a const constant -- read only const string & getnickname()
   37     2.After the method, the value string & getnickname const() indicating that the method cannot modify the class member
   38     Big brother's suggestion: try to use references, and use const early in the code according to the situation
   39     */
   40 
   41 
   42 
   43 
   44     /** setter Is to assign a value to a property in a class,
   45         getter The value of a property of this class*/
   46 
   47     /** get */
   48     const string& GetNickName()
   49     {
   50         return m_NickName;
   51         /**Why return reference, because string m'u nickname means m'u nickname is object type*/
   52     }
   53     int GetLevel() const{return m_Level;}
   54     int GetMaxLife() const{return m_MaxLife;}
   55     int GetCurrLife() const{return m_CurrLife;}
   56 
   57 
   58     /** set */
   59     void SetNickName(const string & nickName)
   60     {
   61         this->m_NickName = nickName;
   62     }
   63     void SetLevel(int level){m_Level = level;}
   64     void SetMaxLife(int maxLife){m_MaxLife = maxLife;}
   65     void SetCurrLife(int currLife){m_CurrLife = currLife;}
   66 };
   67 
   68 /**Warrior.h*/
   69 class Warrior : public Hero // Public inheritance - the most common way of inheritance, embodies the is-a relationship
   70 {
   71 private:
   72     int m_physicalAttack;//The unique member of warrior subclass: physical attack power
   73 
   74 
   75 public:
   76     Warrior();
   77     Warrior(const string& nickName, int level, int maxLife, int currLife, int physicalAttack);
   78     void XiaoQuanQuan();
   79     void HiSunZi();
   80 
   81     int GetphysicalAttack() const{return m_physicalAttack;}
   82     void SetphysicalAttack(int physicalAttack){m_physicalAttack = physicalAttack;}
   83 
   84 };
   85 
   86 void HeroTest();
   87 void WarriorTest();
   88 
   89 int main()
   90 {
   91     HeroTest();
   92     WarriorTest();
   93     return 0;
   94 }
   95 
   96 /**Note: operator < < is overloaded */
   97 
   98 void HeroTest()
   99 {
  100     cout << "Here is HeroTest() :\n";
  101     cout << "Here is Hero1\n";
  102     Hero hero1;//Class instantiation: Method 1
  103     cout << hero1;
  104     hero1.Move();
  105 
  106     cout << "********************************\n\n";
  107 
  108     cout << "Here is Hero2\n";
  109     Hero hero2("Test hero 2 Miyamoto Musashi", 22);//Class instantiation: Method 1
  110     cout << hero2;
  111     hero2.Move();
  112 
  113     cout << "********************************\n\n";
  114 
  115     cout << "Here is Hero3\n";
  116     Hero * hero3 = new Hero("Test Hero 3 Xia Houdun",33,333,3333);//Class instantiation: Method 2: use the pointer new
  117     cout << *hero3;
  118     hero3->Move();
  119     (*hero3).Move(); /** Equivalent to hero2 - > move()*/
  120     delete hero3;
  121 }
  122 
  123 void WarriorTest()
  124 {
  125     cout << "********************************\n";
  126     cout << "********************************\n\n";
  127     cout << "Here is WarriorTest() :\n";
  128 
  129     cout << "Here is Warrior1\n";
  130     Warrior warrior1;
  131     cout << warrior1 << endl;
  132     cout << "The following shows the derived classes Warrior(Subclass)Call base class Hero(Parent class)Of Move()Method:\n";
  133     warrior1.Move();//If the Move method is not implemented in a derived class, the base class Move method will be called by default
  134                     //If the Move method is implemented in a derived class, the Move method of the derived class will be called
  135 
  136     cout << "********************************\n\n";
  137 
  138     cout << "Here is Warrior2\n";
  139     Warrior warrior2("Crazy iron",9,99,999,9999);
  140     cout << warrior2;
  141 
  142 }
  143 
  144 /**Hero.cpp*/
  145 Hero::Hero(): m_NickName("Monkey"), m_Level(1), m_MaxLife(100), m_CurrLife(100)
  146 {
  147     cout << "Here is Hero Default construction of" << endl;
  148 }
  149 
  150 Hero::Hero(const string& nickName): m_NickName(nickName), m_Level(2), m_MaxLife(200), m_CurrLife(200)
  151 {
  152     cout << "Here is Hero The construction of a parameter of" << endl;
  153 }
  154 Hero::Hero(const string& nickName, int level): m_NickName(nickName), m_Level(level), m_MaxLife(300), m_CurrLife(300)
  155 {
  156     cout << "Here is Hero The construction of two parameters of" << endl;
  157 }
  158 Hero::Hero(const string& nickName, int level, int maxLife, int currLife): m_NickName(nickName), m_Level(level),m_MaxLife(maxLife), m_CurrLife(currLife)
  159 {
  160     cout << "Here is Hero The construction of four parameters of" << endl;
  161 }
  162 
  163 void Hero::Move()
  164 {
  165     cout << "Here is Hero Class Move function:" << m_NickName << "Come also"  << endl<< endl;
  166 
  167 }
  168 
  169 ostream& operator<<(ostream& out, Hero& hero)
  170 {
  171     out << "Nickname?: " << hero.GetNickName() << "\n";
  172     out << "Grade: " << hero.GetLevel() << "\n";
  173     out << "Maximum life: " << hero.GetMaxLife() << "\n";
  174     out << "Current life: " << hero.GetCurrLife() << "\n";
  175     return out;
  176 }
  177 
  178 /**Warrior.cpp*/
  179 Warrior::Warrior(): Hero()//Methods of inheriting the parent class Hero
  180 {
  181     cout << "This is the parent class Hero Subclasses Warrior Default construction of!I inherited. Hero Default construction of" << endl;
  182 }
  183 
  184 //Methods of inheriting the parent class Hero
  185 Warrior::Warrior(const string& nickName, int level, int maxLife, int currLife, int physicalAttack): Hero(nickName,level,maxLife,currLife),m_physicalAttack(physicalAttack)
  186 {
  187     //Hero(nickName,level,maxLife,currLife);
  188     cout << "This is subclass Warrior The construction of two parameters of" << endl;
  189     cout << "Current physical attack value:" << GetphysicalAttack() << endl;
  191 }

4.2 operation results

Published 17 original articles, won praise 1, visited 162
Private letter follow

Added by colB on Mon, 13 Jan 2020 12:08:48 +0200