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 }