1.继承和派生 
继承的概念:在定义一个新的类B时,如果该类与某个已有的类A相似(指的是B拥有A的全部特点),那么就可以把A作为一个基类 ,而把B作为基类的一个派生类 (也称为子类)。
派生类是通过对基类进行修改和扩充得到的。在派生类中,可以扩充新的成员变量和成员函数。
派生类一经定义后,可以独立使用,不依赖与基类。 
派生类拥有基类的全部成员变量和成员函数 ,包括private,public,protected
派生类的写法:class 派生类名: public 基类名 { };
派生类的内存空间 :派生类对象的体积,等于基类对象的体积,再加上派生类对象自己的成员变量的体积。在派生类对象中,包含着基类对象,而且基类对象的存储位置位于派生类对象新增的成员变量之前。 
 
1 2 3 4 5 6 class  CBase {    int  v1, v2; }; class  CDerived :public  CBase{    int  v3; } 
示例 :写了一个学生的类Student,再写一个Student类的派生类UndergraduateStudent,补充和修改一些功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <iostream>  #include <string>  using  namespace  std ;class  Student  {private :	string  name; 	string  id; 	char  gender; 	int  age; public :	void  PrintInfo ()   		cout  << "Name: " <<name<< endl ; 		cout  << "ID: "  << id << endl ; 		cout  << "Age: "  << age << endl ; 		cout  << "Gender: "  << gender << endl ; 	} 	void  SetInfo (const  string  &_name, const  string  &_id, int  _age, char  _gender)   		name = _name; 		id = _id; 		age = _age; 		gender = _gender; 	} 	string  GetName ()  return  name; }	 }; class  UndergraduateStudent  :public  Student {  private :	string  department; public :	void  QualifiedForBaoyan ()   		cout  << "qualified for baoyan"  << endl ; 	} 	void  PrintInfo ()   		Student::PrintInfo();   		cout  << "Department:"  << department << endl ; 	} 	void  SetInfo (const  string  &_name, const  string  &_id, int  _age, char  _gender, const  string  &_department)        {		Student::SetInfo(_name, _id, _age, _gender); 		department = _department; 	}	 };  int  main ()  	UndergraduateStudent S; 	S.SetInfo("Harry Potter" , "20200217" , 19 , 'M' , "Machine Learning" ); 	cout  << S.GetName() << " " ; 	S.QualifiedForBaoyan(); 	S.PrintInfo(); 	return  0 ; } 
程序运行结果:
2.继承关系和复合关系 类与类之间有两种关系:
继承 :“是”关系
基类A,B是基类A的派生类 
逻辑上要求:“一个B对象也是一个A对象”,比如上节中Student类和UndergraduateStudent类。 
 
复合 :“有”关系
类C中“有”成员变量k,k是类D的对象,则C和D是复合关系 
一般逻辑上要求:“D对象是C对象的固有属性或组成部分”。 
 
 
举一个简单的例子:如果要写一个小区养狗管理程序,需要写一个“业主”类和“狗”类,狗的主人即是业主,规定狗只能有一个主人,而一个业主最多可以有5条狗。
正确的写法:为”狗“类设一个”业主“类的对象指针;为”业主“类设一个”狗“类的对象指针数组。
1 2 3 4 5 6 7 class  Master ;class  Dog {    Master *m; }; class  Master {    Dog dogs[10 ]; }; 
而以下的做法都是错误的或者不好的:
1 2 3 4 5 6 7 class  Dog ;class  Master {    Dog dogs[10 ]; }; class  Dog {    Master m; };    
1 2 3 4 5 6 7 class  Dog ;class  Master {    Dog *dogs[10 ]; }; class  Dog {    Master m; };    
1 2 3 4 5 6 7 class  Master ;class  Dog {    Master *m; }; class  Master {    Dog dogs[10 ]; };    
3.基类和派生类有同名成员的情况  基类和派生类有时会拥有相同名称的成员变量或者成员函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class  base {    int  j; public :    int  i;     void  func ()  }; class  derived :public  base{public :    int  i;              void  access ()      void  func ()  }; void  derived::access(){    j = 5 ;       i = 5 ;             base::i = 5 ;       func();            base::func();  } int  main ()     derived obj;     obj.i = 3 ;            obj.base::i = 3 ;  } 
obj对象占用的存储空间:
注意:一般来说,基类和派生类不定义同名成员变量 。
4.访问范围说明符 
基类的private成员,可以被下列函数访问:
基类的public成员,可以被下列函数访问:
基类的成员函数 
基类的友元函数 
派生类的成员函数 
派生类的友元函数 
其他的函数 
 
基类的protected成员,可以被下列函数访问:
基类的成员函数 
基类的友元函数 
派生类的成员函数可以访问当前对象的基本的 protected成员  
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class  Father  {private :  int  nPrivate;public :   int  nPublic;protected :int  nProtected;}; class  Son :public  Father{	void  AccseeFather ()   		nPublic = 1 ;       		nPrivate = 1 ;      		nProtected = 1 ;    		Son f; 		f.nProtected = 1 ;  	} }; int  main ()  	Father f; 	Son s; 	f.nPublic = 1 ;      	s.nPublic = 1 ;      	f.nProtected = 1 ;   	f.nPublic = 1 ;      	s.nProtected = 1 ;   	s.nPublic = 1 ;      	return  0 ; } 
5.派生类的构造函数 
派生类对象包含基类对象 
执行派生类构造函数之前,先执行基类的构造函数 
派生类交代基类初始化,具体形式: 
 
1 2 3 4 构造函数名(形参表):基类名(基类构造函数实参表) {      } 
看一个具体的例子 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class  Bug  {private :	int  nLegs; 	int  nColor; public :	int  nType; 	Bug(int  _legs, int  _color); 	void  PrintBug ()   }; class  FlyBug  :public  Bug {	int  nWings; public :	FlyBug(int  _legs, int  _color, int  _wings); }; Bug::Bug(int  _legs, int  _color) { 	nLegs = _legs; 	nColor = _color; } FlyBug::FlyBug(int  _legs, int  _color, int  _wings) { 	nLegs = _legs;     	nColor = _color;   	nType = 1 ;         	nWings = _wings; } FlyBug::FlyBug(int  _legs, int  _color, int  _wings) :Bug(_legs, _color) { 	nWings = _wings; } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class  Base  {public :	int  n; 	Base(int  i):n(i){ 		cout  << "Base"  << n << " constructed"  << endl ; 	} 	~Base() { 		cout  << "Base"  << n << " destructed"  << endl ; 	} }; class  Derived :public  Base {public :	Derived(int  i) :Base(i) { 		cout  << "Derived  constructed"  << endl ; 	} 	~Derived(){ 		cout  << "Derived  destructed"  << endl ; 	} }; int  main ()  	Derived Obj (3 )  ; 	return  0 ; } 
程序运行结果为:
6.public继承的赋值兼容规则 1 2 3 4 class  base {class  derived :public  base{ };base b; derived d; 
派生类的对象可以赋值给基类对象:b = d; 
派生类的对象可以初始化基类引用:base & br = d; 
派生类的对象的地址可以赋给基类指针:base * bp = & d; 
 
注意上述规则不能颠倒,且如果派生方式是private或者protected,上述三条都不可行
7.直接基类与间接基类 C++中类的派生可以是很多层的 。
如类A派生类B,类B派生类C,类C派生类D:
类A是类B的直接基类; 
类B是类C的直接基类,类A是类C的间接基类; 
类C是类D的直接基类,类A、B是类D的间接基类; 
 
在声明派生类时,只需要列出它的直接基类 ;派生类沿用着类的层次自动向上继承它的间接基类。
派生类的成员包括:派生类自己定义的成员,直接基类中的所有成员,所有间接基类的全部成员
当执行构造函数时,从顶层基类开始,依次往下执行基类的构造函数,最后执行自己的构造函数。 
下面看一个例子:Base $\to$ Derived $\to$ MoreDerived 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <iostream>  using  namespace  std ;class  Base  {public :	int  n; 	Base(int  i) :n(i) { 		cout  << "Base"  << n << " constructed"  << endl ; 	} 	~Base() { 		cout  << "Base"  << n << " destructed"  << endl ; 	} }; class  Derived  :public  Base {public :	Derived(int  i) :Base(i) { 		cout  << "Derived  constructed"  << endl ; 	} 	~Derived() { 		cout  << "Derived  destructed"  << endl ; 	} }; class  MoreDerived  :public  Derived {public :	MoreDerived(int  i) :Derived(i) { 		cout  << "MoreDerived  constructed"  << endl ; 	} 	~MoreDerived() { 		cout  << "MoreDerived  destructed"  << endl ; 	} }; int  main ()  	MoreDerived Obj (3 )  ; 	return  0 ; } 
程序运行结果为: