C++ 面向对象的三个特点--继承与封装(二)
顺着上一篇的内容,我们继续来了解继承的基本知识。
-
派生类的构造函数和析构函数
派生类继承了基类的成员,但是不能继承基类的构造函数和析构函数,首先,我们了解构造函数和析构函数的执行顺序是当我们创建一个派生类的对象是,先执行的是基类的构造函数,然后是派生类的构造函数。析构函数则正好相反,先执行派生类的析构函数,再执行基类的析构函数。
-
派生类构造函数和析构函数的构造规则
当基类的构造函数没有参数的时,或者没有显示的定义构造函数时,派生类可以不向基类传递参数,甚至可以不定义构造函数。但是当基类带有含参数的构造函数的时候,派生类必须定义构造函数,以提供把参数传递给基类构造函数的途径。
派生类构造函数的定义格式:
派生类名(参数总表) : 基类名(参数表)
其中基类的构造函数参数通常来源于派生类构造函数的参数总表,也可以设置为常数值。
例:
base:
base(int n)
derived:
derived(int n) : base(n)
或derived() : base(1)
还需注意的几点:
1).如果派生类的基类也是一个派生类,每个派生类只需负责他的直接基类的构造,依次上溯。
2).因为析构函数是不带参数的,在派生类中是否要定义析构函数与它所属的基类无关,它们是各自独立的。
3).派生类中含有内嵌对象成员时,构造函数的一般形式如下:派生类名(参数总表):基类名(参数表),内嵌对象名1(参数表),····,内嵌对象名n(参数表),此时构造函数的执行顺序是基类的构造函数,内嵌对象成员的构造函数(调用顺序按照声明顺序),派生类的构造函数。
EX:
1 // 基类 2 class Base 3 { 4 public: 5 Base(){a = 0;b = 0;} 6 Base(int x,int y) 7 { 8 a = x; 9 b = y; 10 } 11 virtual ~Base(void); 12 13 void print() 14 { 15 printf("\na = %d b = %d", a, b); 16 } 17 18 private: 19 int a,b; 20 }; 21 22 // 派生类 23 class Derivel : 24 private Base 25 { 26 public: 27 Derivel():Base(1, 1) 28 { 29 c = 0; 30 d = 0; 31 } 32 33 Derivel(int x, int y):Base(x + 1, y + 1) 34 { 35 c = x; 36 d = y; 37 } 38 39 Derivel(int x, int y, int m, int n):Base(m, n) 40 { 41 c = x; 42 d = y; 43 } 44 virtual ~Derivel(void); 45 46 void print() 47 { 48 Base::print(); 49 printf(" c = %d d = %d", c, d); 50 } 51 private: 52 int c,d; 53 }; 54 55 // main 56 int _tmain(int argc, _TCHAR* argv[]) 57 { 58 Base obj; 59 obj.print(); 60 61 Derivel obj1; 62 obj1.print(); 63 64 Derivel obj2(10,10); 65 obj2.print(); 66 67 Derivel obj3(10,10,20,20); 68 obj3.print(); 69 70 system("pause"); 71 return 0; 72 }
输出结果:
a = 0 b = 0
a = 1 b = 1 c = 0 d = 0
a = 11 b = 11 c = 10 d = 10
a = 20 b = 20 c = 10 d = 10
-
多重继承和多重继承的构造函数
声明两个及两个以上的基类的派生类称为多重继承。其声明格式一般如下:
Class 派生类名:继承方式1 基类名1,继承方式2 基类名2{
};
注意:当没有写明继承方式的时候按照默认的继承方式认定,默认的继承方式是private。
多重继承中,三种继承方式对于基类成员在派生类中的访问性的规则和单继承是一样的。
多重继承的构造函数的执行顺序与单继承构造函数的执行顺序相同,也是遵循先执行基类中的构造函数,在执行对象成员的构造函数,最后执行派生类的构造函数的原则。在各个基类之间,则严格按照派生类的声明顺序从左到右依次执行。而析构函数的话则是相反的。
EX:
1 // 基类1 2 class Base 3 { 4 public: 5 Base() 6 { 7 printf("Constructor base.\n"); 8 } 9 10 virtual ~Base() 11 { 12 printf("Destructor base.\n"); 13 } 14 }; 15 16 // 基类2 17 class Base1 18 { 19 public: 20 Base1() 21 { 22 printf("Constructor base1.\n"); 23 } 24 25 ~Base1() 26 { 27 printf("Destructor base1.\n"); 28 } 29 }; 30 31 // 派生类 32 class Derivel : 33 private Base,Base1 34 { 35 public: 36 Derivel() 37 { 38 printf("Constructor derivel.\n"); 39 } 40 41 virtual ~Derivel() 42 { 43 printf("Destructor derivel.\n"); 44 } 45 }; 46 47 // main 48 int _tmain(int argc, _TCHAR* argv[]) 49 { 50 Derivel *a = new Derivel(); 51 delete a; 52 53 system("pause"); 54 return 0; 55 }
输出结果:
Constructor base.
Constructor base1.
Constructor derivel.
Destructor derivel.
Destructor base1.
Destructor base.