Only a public derived class is the real sub-type of the base class. It fully inherits the functions of the base class. There is a compatibility relationship between the base class and the object of the derived class. Because the derived class contains members inherited from the base class, the value of the derived class can be assigned to the Base Class Object, when a base class object is used, it can be replaced by its subclass object.
Specific performance in the following aspects:
A derived class object can be assigned a value to a base class object.
You can assign values to the base class objects of a subclass (that is, a common derived class) object. For example
A a1; // defines the base class A Object a1
B b1; // defines the object b1 of Class A's common derived class B
A1 = b1; // use the derived class B object b1 to assign a value to the Base Class Object a1
The members of the derived class are discarded when values are assigned.
In fact, the so-called value assignment only assigns values to data members and does not assign values to member functions. Note: After assigning values, you cannot access the b1 Member of the derived class object through object a1, because the b1 member is different from the a1 member.
Assume that age is a public data member added to B, and analyze the following usage:
A1.age = 23; // error. a1 does not contain the members added to the derived class.
B1.age = 21; // correct. b1 contains the added member in the derived class.
Note that child-type relationships are unidirectional and irreversible. B is the subtype of A. It cannot be said that A is the subtype of B.
The base class object can only be assigned a value to its base class object, rather than a base class object. The reason is obvious because the base class object does not contain members of the derived class, you cannot assign values to the members of a derived class. Similarly, objects of different Derived classes of the same base class cannot be assigned values.
A derived class object can be used to assign values or initialize a base class object.
If you have defined the base class A Object a1, you can define the reference variable a1:
A a1; // defines the base class A Object a1
B b1; // defines the B object b1 of the common derived class
A & r = a1; // defines the reference variable r of the base class A object, and initializes it with a1
In this case, the referenced variable r is the alias of a1, and r and a1 share the same storage unit. You can also use a subclass object to initialize the reference variable r and change the last line above
A & r = b1; // defines the reference variable r of the base class A object and initializes it with b1 of the derived class B object.
Or keep the above 3rd rows "A & r = a1;" and assign A value to r:
R = b1; // use the derived class B object b1 to assign values to the reference variable r of A1.
Note: At this time, r is not the alias of b1, nor does it share the same storage unit with b1. It is only the alias of the basic class in b1. The basic class in r and b1 shares the same storage unit, and r and b1 share the same starting address.
If the parameter of a function is a reference of a base class object or base class object, the corresponding real parameter can be a subclass object. If there is a function
Copy codeThe Code is as follows: fun: void fun (A & r) // The input parameter is the reference variable of the object in Class.
{
Cout <r. num <endl;
} // Output the data member num of the referenced variable
The parameter of the function is A reference variable of the object of Class A. The actual parameter should be an object of Class. Because the subclass object is compatible with the value assignment of the derived class object, the type of the derived class object can be automatically converted. when calling the fun function, you can use the b1 object of the derived class B as the real parameter: fun (b1 ); output the value of num, a base-class data member of object b1 of Class B. As before, only the values of basic class members in the derived class can be output in the fun function.
The address of the derived class object can be assigned to the pointer variable of the base class object, that is, the pointer variable of the base class object can also point to the derived class object.
Example 11.10 defines a base class Student (Student), then defines the public derived class Graduate (Graduate) of the Student class, and outputs data by pointing to the pointer of the base class object. In this example, the pointer to the base class object is used to point to the derived class object. To reduce the program length, only a few Members are set in each class. Only num (student ID), name (name), and score (score) data members are set for the student category. The Graduate class only adds one data member pay (salary ).
The 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 // declare the Student class
{
Public:
Student (int, string, float); // declare the constructor
Void display (); // declare the output function
Private:
Int num;
String name;
Float score;
};
Student: Student (int n, string nam, float s) // defines the constructor.
{
Num = n;
Name = nam;
Score = s;
}
Void Student: display () // defines the output function
{
Cout <endl <"num:" <num <endl;
Cout <"name:" <name <endl;
Cout <"score:" <score <endl;
}
Class Graduate: public Student // declare the public derived class Graduate
{
Public:
Graduate (int, string, float, float); // declare the constructor
Void display (); // declare the output function
Private:
Float pay; // salary
};
// Define the constructor
Void Graduate: display () // defines 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); // defines Student Class Object stud1
Graduate grad1 (2001, "Wang", 98.5, 563.5); // defines the Graduate class Object grad1
Student * pt = & stud1; // defines the 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 will think that there are two display member functions with the same name in the derived class. According to the rule of overwriting with the same name, the display function of the Graduate object of the derived class should be called, and the Graduate :: when the display function is used, Student: display function is called to output num, name, and score, and then the pay value.
In fact, this inference is wrong. Let's take a look at the output results of the program.:
Num: 1001
Name: Li
Score: 87.5
Num: 2001
Name: wang
Score: 98.5
No pay value is output.
The problem is that pt is a pointer variable pointing to a Student class object. Even if it points to grad1, pt actually points to the part inherited from the base class in grad1.
By pointing to the Base Class Object Pointer, you can only access the base class members in the derived class, but not the members added to the derived class. Therefore, pt-> display () calls not the display function added by the Graduate object of the derived class, but the display function of the base class. Therefore, only the num, name, and score3 data of grad1 are output.
If you want to output the pay of graduate grad1 through pointers, you can set another pointer variable ptr pointing to the object of the derived class to point to grad1, and then use ptr-> display () call the display function of the derived class object. But this is not convenient.
In this example, we can see that it is legal and safe to point the pointer variable pointing to the subclass object of the base class object without any compilation errors. However, applications cannot fully satisfy people's hopes. Sometimes, people want to use base class pointers to call Members of base classes and subclass objects.
In the next section, we will solve this problem by using virtual functions and polymorphism.