Deep parsing of the constructors of derived classes in C + + _c language

Source: Internet
Author: User

The constructor of a base class cannot be inherited, and when a derived class is declared, the initialization of inherited member variables is also done by the constructor of the derived class. So when you design a constructor for a derived class, you need to consider not only the new member variables of the derived class, but also the member variables of the base class, so that they are initialized.

The idea for solving this problem is to call the constructor of the base class when the constructor of the derived class is executed.

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

#include <iostream>
using namespace std;
Base class class
people{
protected:
  char *name;
  int age;
Public:
  people (char*, int);
People::P eople (char *name, int age): Name (name), age (age) {}
//derived class class
student:public people{
Private :
  float score;
Public:
  Student (char*, int, float);
  void display ();
Constructor
Student::student (char *name, int age, float score) was invoked for the base class: People (name, age) {
  This->score = score;< c22/>}
void Student::d isplay () {
  cout<<name<< "age is" <<age<< ", the result is" <<score <<endl;
}
int main () {
  Student stu ("Xiaoming", 90.5);
  Stu.display ();
  return 0;
}

The results of the operation are:
Xiaoming's age is 16, and his grade is 90.5.

Please note that line 23rd of the code:

Student::student (char *name, int age, float score): People (name, age)


This is the constructor of the derived class Student. The colon is preceded by the head of the derived class constructor, this is the same as the constructor we introduced earlier, but its formal parameter list includes the data needed to initialize the base class and the member variables of the derived class, followed by a call to the base class constructor, which is very similar to the parameter initialization table of the normal constructor.

In fact, you can put the invocation of the base class constructor together with the parameter initialization table, as follows:

Student::student (char *name, int age, float score): People (name, age), score (score) {}


The base class constructor and the initialization table are separated by commas.

Note that the colon is followed by a call to the base class constructor, not a declaration, so the arguments in parentheses are arguments, which can be not only arguments in the parameters of a derived class constructor, but also local variables, constants, and so on. As shown below:

Student::student (char *name, int age, float score): People ("Lilei", 20)


Base class constructor Call rule

In fact, you must call the constructor of the base class when you create an object from a derived class, which is a syntax rule. That is, it is best to specify a base class constructor when defining a derived class constructor, or to call the default constructor of the base class (without a constructor with a parameter) if it is not specified, or if there is no default constructor, then the compilation fails.

Take a look at the following example:

#include <iostream>
using namespace std;
Base class class
people{
protected:
  char *name;
  int age;
Public:
  people ();
  People (char*, int);
};
People::P eople () {
  this->name = "xxx";
  this->age = 0;
}
People::P eople (char *name, int age): Name (name), age (age) {}
//derived class class
student:public people{
Private :
  float score;
Public:
  Student ();
  Student (char*, int, float);
  void display ();
Student::student () {
  this->score = 0.0;
}
Student::student (char *name, int age, float score): People (name, age) {
  this->score = score;
}
void Student::d isplay () {
  cout<<name<< "age is" <<age<< ", the result is" <<score<<endl;
}
int main () {
  Student stu1;
  Stu1.display ();
  Student stu2 ("Xiaoming", 90.5);
  Stu2.display ();
  return 0;
}

Run Result:

XXX's age is 0, the result is 0
Xiaoming's age is 16, the result is 90.5


When you create an object stu1, the constructor of the derived class student::student () does not indicate which constructor of the base class to call, and from the results of the operation it is obvious that the system calls the constructor without parameters by default, which is people::P eople ().

When an object STU2 is created, the constructor of the derived class is executed student::student (char *name, int age, float score), which indicates the constructor of the base class.

In line 31st, if you remove people (name, age), the default constructor is also invoked, and the output of Stu2.display () changes to:
The age of XXX is 0, the result is 90.5

If you delete a constructor with no parameters in the base class people, a compilation error occurs because the base class constructor is not invoked when the object STU1 is created.

Summary: If the base class has a default constructor, you can not specify in the derived class constructor that the system will call by default, and if not, you must indicate that the system does not know how to call the constructor of the base class.
Call Order of constructors

To make sense of this, let's take a look at an example:

#include <iostream>
using namespace std;
Base class class
people{
protected:
  char *name;
  int age;
Public:
  people ();
  People (char*, int);
};
People::P eople (): Name ("XXX"), age (0) {
  cout<< "people::P eople ()" <<endl;
}
People::P eople (char *name, int age): Name (name), age (age) {
  cout<< "people::P eople (char *, int)" <<endl ;
}
Derived class
class Student:public people{
private:
  float score;
Public:
  Student ();
  Student (char*, int, float);
Student::student (): Score (0.0) {
  cout<< "student::student ()" <<endl;
}
Student::student (char *name, int age, float score): People (name, age), score (score) {
  cout<< "Student:: Student (char*, int, float) "<<endl;
}
int main () {
  Student stu1;
  cout<< "--------------------" <<endl;
  Student stu2 ("Xiaoming", 90.5);
  return 0;
}

Run Result:

People::P eople ()
student::student ()
--------------------
people::P eople (char *, int)
Student:: Student (char*, int, float)

It is clear from the run result that when you create a derived class object, you call the base class constructor and then the derived class constructor. If the inheritance relationship has several layers, for example:
A--> B--> C
Then, when you create a Class C object, the execution order of the constructors is:
Class A constructors--> Class B constructors--> Class C constructors
The invocation order of the constructors is Top-down, from the base class to the derived class, according to the inherited hierarchy.

C + + constructors for derived classes with child objects
A data member of a class can be either a standard type (such as int, char) or a system-supplied type (such as String), or it can contain a class object, such as a data member that can be included when declaring a class:

  Student S1; Student is a declared class name, S1 is an object of the student class


At this point, S1 is the inline object in the class object, called the child object (Subobject), the object in the object.


So, how do you initialize the object when initializing the data member? Carefully analyze the following procedure, paying special attention to the method of writing derived class constructors.

[Example] a constructor that contains a derived class of child objects. To simplify the program for easy reading, there are only two data members in the base class student, that is, NUM and name.

#include <iostream> #include <string> using namespace std;
   Class student//declares the base class {public://Common part Student (int n, string nam)//base class constructor, as in example 11.5 {num=n;
  Name=nam; } void Display ()//member function, output base class data member {cout<< "num:" <<num<<endl<< "Name:" <<name<<end
  L
  } protected://Protect part int num;
String name;
}; Class Student1:public Student//Declaration Common derived class Student1 {public:student1 (int n, string nam,int n1, String nam1,int A, string
   AD): Student (N,nam), monitor (N1,NAM1)//derived class constructor {age=a;
  Addr=ad;
   } void Show () {cout<< ' This student is: ' <<endl; Display (); Output num and name cout<< "Age:" <<age<<endl; Output age cout<< ' Address: ' <<addr<<endl<<endl;
   Output addr} void Show_monitor ()//member function, output child object {cout<<endl<< "Class monitor is:" <<endl; Monitor.display (); Call the base class member function} private:///derived class Student monitor;
  Defines the child object (monitor) int age;
String addr;};
  int main () {Student1 stud1 (10010, "Wang-li", 10001, "Li-sun", "+ Beijing Road,shanghai"); Stud1.show (); Output the student's data stud1.show_monitor ();
Output child object's data return 0;
 }

The output at run time is as follows:

This student is:
num:10010
name:wang-li
age:19
address:115 Beijing
Class Monitor is:
num:10001
Name:li-sun

Note that you have a data member in the derived class Student1:

  Student Monitor;  Define child Objects monitor (monitor)

The type of "monitor" is not a simple type (such as int, char, float, etc.), it is an object of the student class. We know that the data members of the object should be initialized when it is established. So how do you initialize the object? It is obviously not possible to initialize a derived class when it is declared (such as Student Monitor (10001, "Li-fun"), because the class is an abstract type, just a model that cannot have concrete data, and the child objects of each derived class object are generally different (for example, student A, B, C's Monitor is a, and the student D, E, F's monitor is F. Therefore, the initialization of a child object is achieved by invoking the derived class constructor when the derived class is established.

The task of a derived class constructor should include 3 parts:

    1. initializes the base class data member;
    2. Initialization of the child object data member;
    3. Initializes the derived class data member.

The first part of the constructor of a derived class in a program is as follows:

  Student1 (int n, string nam,int n1, String nam1,int A, string AD):
    Student (N,nam), monitor (N1,NAM1)


There are 6 formal parameters in the above constructor, the first two as arguments to the base class constructor, the first 3, the 4th as the parameters of the child object constructor, and the 5th and 6th are used as the derived class data member initialization.

To sum up, the general form of defining derived class constructors is: derived class constructor name (total parameter table column): base class constructor name (Parameter table column), child object name (parameter table column)
{
New number of member initialization statements in derived classes
}

The order in which the derived class constructors are executed is:
Call the base class constructor to initialize the base class data member;
Invokes the child object constructor and initializes the sub object data member;
Then executes the derived class constructor itself, initializing the derived class data member.

The parameters in the total Parameter table column of the derived class constructor should include the parameters in the parameter table columns of the base class constructor and child objects. The order of the base class constructors and child objects can be arbitrary, as the first part of the derived class constructor can be written as

  Student1 (int n, string nam,int n1, String nam1,int A, string AD): Monitor (N1,NAM1), Student (N,nam)


The compilation system establishes their transitive relationships based on the same parameter names, rather than on the order of the parameters. But it is customary to write the base class constructor first.

If you have more than one child object, and so on, the derived class constructor should list each of the child object names and their parameter table columns.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.