c++之继承与派生

来源:互联网 发布:林彪军事才能 知乎 编辑:程序博客网 时间:2024/05/18 00:52

(一)继承的概念:

继承(Inheritance)可以理解为一个类从另一个类获取成员变量和成员函数的过程。例如类 B 继承于类 A,那么 B 就拥有 A 的成员变量和成员函数。被继承的类称为父类或基类,继承的类称为子类或派生类。


(二)继承权限与继承方式

1.C++继承的一般语法为:

class 派生类名:[继承方式] 基类名
{
    派生类新增加的成员
};
继承方式限定了基类成员在派生类中的访问权限,包括 public(公有的)、private(私有的)和 protected(受保护的)。此项是可选项,如果不写,默认为 private(成员变量和成员函数默认也是 private)。
 
现在我们知道,public、protected、private 三个关键字除了可以修饰类的成员,还可以指定继承方式。


2.继承权限

1) public继承方式
基类中所有 public 成员在派生类中为 public 属性;
基类中所有 protected 成员在派生类中为 protected 属性;
基类中所有 private 成员在派生类中不能使用。
 
2) protected继承方式
基类中的所有 public 成员在派生类中为 protected 属性;
基类中的所有 protected 成员在派生类中为 protected 属性;
基类中的所有 private 成员在派生类中不能使用。
 
3) private继承方式
基类中的所有 public 成员在派生类中均为 private 属性;
基类中的所有 protected 成员在派生类中均为 private 属性;
基类中的所有 private 成员在派生类中不能使用。


(三)继承中的构造析构调用原则 

1构造析构调用原则 

1)子类对象在创建时会首先调用父类的构造函数
2)父类构造函数执行结束后,执行子类的构造函数
3)当父类的构造函数有参数时,需要在子类的初始化列表中显示调用
4)析构函数调用的先后顺序与构造函数相反

2 继承与组合混搭下的调用原则

原则:   先构造父类,再构造成员变量、最后构造自己
             先析构自己,在析构成员变量、最后析构父类
             //先构造的对象,后释放


#include using namespace std; class Object{public:    Object(int a)    {        this->a = a;        cout << "Object 构造函数 : "  << a <<  endl;    }     ~Object()    {        cout << "Object 析构函数: " << this->a << endl;    }private:    int a;}; class Parent{public:    Parent(int a, int b)    {        cout << "parent 构造函数" << endl;    }    ~Parent()    {        cout << "parent 析构函数" << endl;    }private:    int a;    int b;}; class Child : public Parent{public:    Child(int c):obj1(1), Parent(2, 3),  obj2(2)    {        cout << "child 构造函数" << endl;    }    ~Child()    {        cout << "child 析构函数" << endl;    } private:    int c;    Object obj1;    Object obj2;}; int main(){    {        Child ch(4);    }     return 0;}

结果是先构造父类,在构造混搭obj1,obj2,在构造自己,析构正好相反


3继承中的同名成员变量处理方法 

1)当子类成员变量与父类成员变量同名时
2)子类依然从父类继承同名成员
3)在子类中通过作用域分辨符::进行同名成员区分(在派生类中使用基类的同名成员,显式地使用类名限定符) 
4)同名成员存储在内存中的不同位置


4.派生类中的static关键字

继承和static关键字在一起会产生什么现象哪?
理论知识
基类定义的静态成员,将被所有派生类共享
根据静态成员自身的访问特性和派生类的继承方式,在类层次体系中具有不同的访问性质 (遵守派生类的访问控制)
派生类中访问静态成员,用以下形式显式说明:类名 :: 成员   或通过对象访问   对象名 . 成员 
总结:
1> static函数也遵守3个访问原则
2> static易犯错误(不但要初始化,更重要的显示的告诉编译器分配内存)
 


(四)多继承

1. 一个类有多个直接基类的继承关系称为多继承

     多继承声明语法
    class  派生类名 : 访问控制  基类名1 ,  访问控制  基类名2 ,  … , 访问控制  基类名n
    {
         数据成员和成员函数声明
    };
    类 C 可以根据访问控制同时继承类 A 和类 B 的成员,并添加自己的成员


2. 多继承的派生类的构造和访问:

多个基类的派生类构造函数可以用初始式调用基类构造函数初始化数据成员
执行顺序与单继承构造函数情况类似。多个直接基类构造函数执行顺序取决于定义派生类时指定的各个继承基类的顺序。
 一个派生类对象拥有多个直接或间接基类的成员。不同名成员访问不会出现二义性。如果不同的基类有同名成员,派生类对象访问时应该加以识别。


3.虚继承

如果一个派生类从多个基类派生,而这些基类又有一个共同的基类,则在对该基类中声明的名字进行访问时,可能产生二义性
  如果在多条继承路径上有一个公共的基类,那么在继承路径的某处汇合点,这个公共基类就会在派生类的对象中产生多个基类子对象
  要使这个公共基类在派生类中只产生一个子对象,必须对这个基类声明为虚继承,使这个基类成为虚基类。
  虚继承声明使用关键字       virtual


4.C++向上转型原则:

类其实也是一种数据类型,也可以发生数据类型转换,不过这种转换只有在基类和派生类之间才有意义,并且只能将派生类赋值给基类,包括将派生类对象赋值给基类对象、将派生类指针赋值给基类指针、将派生类引用赋值给基类引用,这在 C++ 中称为向上转型(Upcasting)。相应地,将基类赋值给派生类称为向下(Downcasting)。

 
向上转型非常安全,可以由编译器自动完成;向下转型有风险,需要程序员手动干预。


5.兼容性原则:

类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。通过公有继承,派生类得到了基类中除构造函数、析构函数之外的所有成员。这样,公有派生类实际就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。
类型兼容规则中所指的替代包括以下情况:
子类对象可以当作父类对象使用
子类对象可以直接赋值给父类对象
子类对象可以直接初始化父类对象
父类指针可以直接指向子类对象
父类引用可以直接引用子类对象
在替代之后,派生类对象就可以作为基类的对象使用,但是只能使用从基类继承的成员。
类型兼容规则是多态性的重要基础之一。


(五)总结

1继承是面向对象程序设计实现软件重用的重要方法。程序员可以在已有基类的基础上定义新的派生类。
2 单继承的派生类只有一个基类。多继承的派生类有多个基类。
3 派生类对基类成员的访问由继承方式和成员性质决定。
4创建派生类对象时,先调用基类构造函数初始化派生类中的基类成员。调用析构函数的次序和调用构造函数的次序相反。
5 C++提供虚继承机制,防止类继承关系中成员访问的二义性。
6 多继承提供了软件重用的强大功能,也增加了程序的复杂性。


原创粉丝点击