C++ derived class and base class conversion rules

  • 2020-04-01 21:30:13
  • OfStack

Only the common derived class is a true subtype of the base class, which fully inherits the functionality of the base class. There is an assignment compatibility relationship between the base class and the derived class object. Since the derived class contains members inherited from the base class, the value of the derived class can be assigned to the base class object, and the subclass object can be substituted when the base class object is used.
Specific performance in the following aspects :
Derived class objects can assign values to base class objects.
You can assign values to base class objects with subclass (that is, public derived class) objects. Such as
A, a1. // define the base class A object a1
B, b1; // defines object b1 of class B, A common derivative of class A
A1 = b1; // assign value to base class object a1 with derived class B object b1
Dismember a derived class's own members when assigning a value.
In fact, the so-called assignment is only for data members, there is no assignment problem for member functions. Note: you cannot attempt to access the members of the derived class object b1 through object a1 after assignment, because the members of b1 are different from the members of a1.
Assuming that age is a public data member added to the derived class B, analyze the following usage:
A1. Age = 23; // error, a1 does not contain additional members in derived classes
B1. The age = 21; // correct, b1 contains the added members of the derived class
It should be noted that the subtype relationship is one-way and irreversible. B is A subtype of A, you can't say A is A subtype of B.
You can only assign a value to a base class object with a subclass object, and you cannot assign a value to a subclass object with a base class object, for obvious reasons, because a base class object does not contain a member of a derived class and cannot assign a value to a member of a derived class. Similarly, you cannot assign values between different derived class objects of the same base class.
A derived class object can assign or initialize a reference to a base class object instead of a base class object.
If base class A object a1 has been defined, reference variables of a1 can be defined:
A, a1. // define the base class A object a1
B, b1; // defines a common derived class B object b1
A & r = a1; // defines the reference variable r for the base class A object and initializes it with a1
At this point, the reference variable r is an alias to a1, which shares the same storage location. You can also initialize the reference variable r with a subclass object, changing the last line above to
A & r = b1; // defines the reference variable r for the base class A object and initializes it with the derived class B object b1//
Or leave the third line "A& r=a1;" , and reassign r to:
R = b1; // the reference variable r of a1 is assigned with the derived class B object b1
Note: at this point, r is not an alias for b1 and does not share the same segment of storage with b1. It is just an alias name for the base class part of b1. R shares the same storage location with the base class part of b1, and r has the same starting address with b1.
If the argument to a function is a base class object or a reference to a base class object, the corresponding arguments can be subclass objects. If I have a function
 
fun: void fun(A& r)//A parameter is A reference variable to an object of class A
{ 
cout<<r.num<<endl; 
} //Output the data member num of the referenced variable
 The formal parameter of a function is a class A Is the reference variable of the object A Object of a class. Because subclass objects are compatible with derived class object assignments, derived class objects can automatically convert types in a call fun A derived class can be used for functions B The object of b1 For arguments : fun(b1);  Output class B The object of b1 Base class data member num The value of the. Same as before, in fun A function can only output values for base class members in derived classes.  
 The address of a derived class object can be assigned to a pointer to a base class object, that is, a pointer to a base class object can also be assigned to a derived class object.  
 case 11.10  Define a base class Student( students ) To define the Student A common derived class of the Graduate( A graduate student ) .   Output data with Pointers to base class objects. The main purpose of this example is to show that Pointers to base class objects are used to point to derived class objects. In order to reduce the program length, only a few members are set in each class. Student class only num( Student id ),name( The name ) and score( results )3 Data members, Graduate Class adds only one data member pay( wage ) .  
 Procedure is as follows : 
[code] 
#include <iostream> 
#include <string> 
Graduate::Graduate(int n, string nam,float s,float p):Student(n,nam,s),pay(p){ } 
using namespace std; 
class Student//The statement Student class
{ 
public : 
Student(int, string,float );//Declaration constructor
void display( );//Declare output function
private : 
int num; 
string name; 
float score; 
}; 
Student::Student(int n, string nam,float s) //Define the constructor
{ 
num=n; 
name=nam; 
score=s; 
} 
void Student::display( )//Define the output function
{ 
cout<<endl<< " num: " <<num<<endl; 
cout<< " name: " <<name<<endl; 
cout<< " score: " <<score<<endl; 
} 
class Graduate:public Student//Declare a common derived class Graduate
{ 
public : 
Graduate(int, string ,float ,float );//Declaration constructor
void display( );//Declare output function
private : 
float pay;//wage
}; 
//Define the constructor
void Graduate::display() //Define the output function
{ 
Student::display(); //Call the display function of the Student class
cout<< " pay= " <<pay<<endl; 
} 
int main() 
{ 
Student stud1(1001, " Li " ,87.5); //Define the Student class object stud1
Graduate grad1(2001, " Wang " ,98.5,563.5); //Define the Graduate class object grad1
Student *pt=&stud1;//Defines a pointer to the Student class object and points to stud1
pt->display( ); //Call the stud1.display function
pt=&grad1; //Pointer to grad1
pt->display( ); //Call the grad1.display function
} 

Many readers would think that: there are two display member functions with the same name in the derived class. According to the rule of the same name overwrite, the called display function of the derived class Graduate object should be called. During the execution of the Graduate::display function, the Student::display function is called, num,name,score is output, and then the value of pay is output.
In fact, this inference is wrong. Let's look at the output of the program :
Num: 1001
Name: Li
Score: 87.5
Num: 2001
Name: wang
Score: 98.5
The value of pay is not printed.
The problem is that pt is a pointer to an object of the Student class, and even if it points to grad1, it actually points to the part of grad1 that is inherited from the base class.
By pointing to the base class object, you can only access the base class members in the derived class, not the members added by the derived class. So the pt - > Display () calls not the display function added by the derived class Graduate object, but the display function of the base class, so only num,name, and score3 data of Graduate student grad1 are output.
If you want to output graduate grad1's pay by pointer, you can set another pointer variable PTR to the derived class object, make it point to grad1, and then use PTR -> Display () calls the display function of the derived class object. But this is inconvenient.
As you can see from this example, it is legal and safe to point a pointer variable to a subclass object with a pointer to the base class object, and there are no compilation errors. But in the application can not satisfy people's hope completely, people sometimes hope to be able to call the members of the base class and subclass object by using the base class pointer.
And we'll do that in the next lecture, using virtual functions and polymorphism

Related articles: