Inheritance and derivative (a)

1, related concepts

In C ++ reusable nature (software reusability) is achieved through inheritance (inheritance) this mechanism. A new class obtains its existing features from an existing class there, a phenomenon known as class inheritance. Create a new sub-class from an existing class (parent class), known as the derived class. Derived class is a concrete base class, the base class and the derived class is abstract.

Public class name with a front base is referred to as "common inherited (public Inheritance)."

The general form for the declaration of the derived class

class derived class name: [inheritance] base class name

{

Newly added members of the derived class

} ;

Inheritance include: public (public), private (private) and protected (protected), this is optional, if you do not write this, it defaults to private (private). The so-called public, is that a variable or function defined outside the class can refer to, while private, then the variable or function definition can only be used in the class, a protected means can not be referenced outside, but can be derived members of the class reference.

    A derived class structure comprising part of the work 3: 

(1) the receiving member from the base class. All members of the derived class to the base class (not including constructors and destructors) taken over.

(2) adjusting the receiving member from the base class. Receiving base class members who can not select a program, but the program can make some adjustments to these members.

(3) an increase in the declaration of the derived class member.

Further, when a derived class declaration, their general should also define a constructor and destructor derived class, because the constructor and destructor are not inherited from the base class.

In a derived class, members have access to four different attributes:  

① outside public, within the derived class and derived class can access.

② protected, access to the derived class, the derived class can not be accessed outside, the next layer derived classes can access.

③ private, within the derived class can be accessed outside the derived class can not access.

④ inaccessible, inside and outside the derived class derived class can not access.
2, inheritance

Members of the public and protected members (1) public inheritance (public inheritance) access to maintain the original base class properties in a derived class, its base class private members remain private.

Members of the public and protected members (2) private inheritance (private inheritance) of the base class become private members of the derived class. Its base class private members still private.
Members of the public and protected members (3) Inheritance (protected inheritance) protected base class in a derived class become protected members of its base class private members remain private. To protect members of the mean is: can not be referenced outside, but can be referenced by members of the derived class.

When defining a derived class to specify a base class inheritance is protected, called inheritance protection, protection established by the derived class inheritance is called a derived class protected (protected derived class), which is the base class called protected group class (protected base class), referred to as a protecting group class.

stud.display (); // call to the public member functions of the base class, the base class data value output member

stud.display_1 (); // call to the public member function of the derived class, the derived class value output data members
    that do not require re-down function inherited class may inherit a proprietary manner it concealed so that the next layer the derived class can not access any of its members. You can know: a member of the derived attributes in different access levels might be different. It is related to inheritance.

Private and protected inheritance way need to be very careful when using, generally not used. In practice, commonly used is the common inheritance.

Private members of the base class after the derived class inherits becomes inaccessible members, all members of the derived class can not access them. If you need to refer to some members of the base class in a derived class, these members of the base class should be declared as protected, and not declared as private.

3, type of inheritance

1) single inheritance

Only a derived class derived from a base class, which is called single inheritance (single inheritance).
2) multiple inheritance

A derived class with two or more base classes referred to as multiple inheritance (multiple inheritance). Avoid deep and multiple inheritance.

Such as:

class D:public A,private B,protected C

Class D {} the newly added member

The constructor of the form:

Derived class constructor function name (parameter list column total): 1 base class constructor (parameter table columns), the base class constructor 2 (parameter table columns), the base class constructor 3 (parameter table column)

{Number of new members of the derived class data member initialization statements}

       The order of each arbitrary base class. The execution order of the derived class constructor is the same: first call the constructor for the base class, then perform the function body of the derived class constructor. Sequentially calls the base class constructor is occurring in accordance with the order of the base class derived class declaration.

 Graduate(string nam,int a,char s, string t,float sco,float w):

        Teacher(nam,a,t),Student(nam,s,sco),wage(w) { }

nam Teacher and Student name assigned to the two classes of property, essentially a man.

When the reference data indicating its scope a member function in the member, such as

cout << "name:" << Teacher :: name << endl; it does not cause ambiguity.

A) ambiguity problem

(1) two members of the base class of the same name

A base class name can be defined:

c1.A :: a = 3; // reference data base member c1 object of a class A

c1.A :: display (); member function display // calls the base class of the object A c1

(2) two base and derived classes of the three members has the same name

 Members of the base class of the same name to be shielded in a derived class, a "invisible".

c1.display( ); 

c1.A :: display (); // member function display represents a derived object c1 in the base class A

c1.B :: display (); // represents a member function in the display c1 derived class object base class B is

(3) if the classes A and B are from the same base class

c1.A :: a = 3; c1.A :: display (); // be accessed by members of a class is the base class to the derived class N in A
4, access attribute derived class

(1) the base class member function can access base class members.

Member function (2) of the derived class can access the derived class to increase their own members.

(3) member function of the derived class to access members of the base class:

基类的成员函数只能访问基类的成员,而不能访问派生类的成员

(4) 派生类的成员函数访问基类的成员:

如继承中所讨论的。

(5) 在派生类外访问派生类的成员:

在派生类外可以访问派生类的公用成员,而不能访问派生类的私有成员。

(6) 在派生类外访问基类的成员:

如继承中所讨论的。
5、派生类的构造函数和析构函数

在设计派生类的构造函数时,不仅要考虑派生类所增加的数据成员的初始化,还应当考虑基类的数据成员初始化:在执行派生类的构造函数时,调用基类的构造函数。

简单的派生类只有一个基类,而且只有一级派生(只有直接派生类,没有间接派生类),在派生类的数据成员中不包含基类的对象(即子对象)。
1)简单的派生类的构造函数

其一般形式为

派生类构造函数名(总参数表列): 基类构造函数名(参数表列)

  {派生类中新增数据成员初始化语句}


Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s) 

 //派生类构造函数

{age=a;   //在函数体中只对派生类新增的数据成员初始化

 addr=ad;

}

在类中对派生类构造函数作声明时,不包括基类构造函数名及其参数表列,只在定义函数时才将它列出。

不仅可以利用初始化表对构造函数的数据成员初始化,而且可以利用初始化表调用派生类的基类构造函数,实现对基类数据成员的初始化。也可以在同一个构造函数的定义中同时实现这两种功能。

Student1(int n, string nam,char s,int a, string ad): Student(n,nam,s), age(a),addr(ad){}

执行构造函数的顺序是: ①派生类构造函数先调用基类构造函数;②再执行派生类构造函数本身(即派生类构造函数的函数体)。

在派生类对象释放时,先执行派生类析构函数~Student1( ),再执行其基类析构函数~Student( )。
2)有子对象的派生类的构造函数

定义派生类构造函数的一般形式为

派生类构造函数名(总参数表列): 基类构造函数名(参数表列),子对象名(参数表列)

  {派生类中新增数成员据成员初始化语句}

执行派生类构造函数的顺序是: 

① 调用基类构造函数,对基类数据成员初始化;

② 调用子对象构造函数,对子对象数据成员初始化;

③ 再执行派生类构造函数本身,对派生类数据成员初始化。

派生类构造函数的总参数表列中的参数,应当包括基类构造函数和子对象的参数表列中的参数。基类构造函数和子对象的次序可以是任意的,如果有多个子对象,派生类构造函数的写法依此类推,应列出每一个子对象名及其参数表列。

  Student1(int n, string nam,int n1, string nam1,int a, string ad)

      :Student(n,nam),monitor(n1,nam1) //派生类构造函数

      {......}

#include <iostream>

#include <string>

using namespace std;

class Student

{

public:

 Student(int n,string nam)

 {

 num=n;

 name=nam;

 }

 void display()

 {

 cout<<"num:"<<num<<endl<<"name:"<<name<<endl;

 }

protected:

 int num;

 string name;

};

class Student1:public Student

{

public:

 Student1(int n,string nam,int n1,string nam1,int a,string ad):Student(n,nam),monitor(n1,nam1)

 {

 age=a;

 addr=ad;

 }

 void show()

 {

 cout<<"this student is:"<<endl;

 display();

 cout<<"age:"<<age<<endl;

 cout<<"addr:"<<addr<<endl<<endl;

 }

 void show_monitor()

 {

 cout<<endl<<"Class monitor is:"<<endl;

 monitor.display();

 }

private:

 Student monitor;

 int age;

 string addr;

};

int main()

{

Student1 stud1(10010,"walg le",10001,"Li-sum",19,"115 beijing road,shanghai");

stud1.show();

stud1.show_monitor();

return 1;

}

3)多层派生时的构造函数

 Student1(int n,char nam[10],int a):Student(n,nam)//派生类构造函数

 Student2(int n, string nam,int a,int s):Student1(n,nam,a)

在声明Student2类对象时,调用Student2构造函数;在执行Student2构造函数时,先调用Student1构造函数;在执行Student1构造函数时,先调用基类Student构造函数。初始化的顺序是: 

① 先初始化基类的数据成员。

② 再初始化Student1的数据成员。

③ 最后再初始化Student2的数据成员。

当不需要对派生类新增的成员进行任何初始化操作时,派生类构造函数的函数体可以为空,即构造函数是空函数

Student1(int n, strin nam,int n1, strin nam1):Student(n,nam),
monitor(n1,nam1) { }

      如果在基类中没有定义构造函数,或定义了没有参数的构造函数,那么在定义派生类构造函数时可不写基类构造函数。

4)派生类的析构函数 

    在派生时,派生类不能继承基类的析构函数,需要通过派生类的析构函数去调用基类的析构函数。在派生类中可以根据需要定义自己的析构函数,用来对派生类中所增加的成员进行清理。在执行派生类的析构函数时,系统会自动调用基类的析构函数和子对象的析构函数,对基类和子对象进行清理。调用的顺序与构造函数相反: 先执行派生类自己的析构函数,对派生类新增加的成员进行清理,然后调用子对象的析构函数,最后调用基类的析构函数。

 

发布了208 篇原创文章 · 获赞 30 · 访问量 1万+

Guess you like

Origin blog.csdn.net/hopegrace/article/details/104250541