浅谈C++继承

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CY071512/article/details/80037752

  如今的面向对象的语言特性都包括抽象、封装、继承、多态四个特点,C++也同样,那么什么是继承?
  


继承的基本概念

  继承是面向对象复用的重要手段。通过继承定义一个类,继承是类型之间的关系建模,共享公有的东西,实现各自本质不同的东西。C++的继承关系就好比生活中的家庭关系一样,比如说你家里有两个矿,那么作为孩子的你将来肯定是要继承你父母给你留的财产,并在原有的基础上你会开辟自己的东西,将你家的矿做的也来越大(手动滑稽),这就是继承。
  继承就好比父亲和儿子的关系,所以也就有了父类(基类)和子类(派生类)。儿子也会传宗接代,也就是说儿子以后也会成为父亲,所以子类也可能成为父类,这也叫多继承
  
1.继承方式:
  继承分为公有继承、私有继承、保护继承

继承方式 基类的public成员 基类的protected成员 基类的private成员 继承引起的访问控制关系的变化
public继承 仍为public成员 仍为protected成员 不可见 基类的非私有成员在子类中访问属性都不变
protected继承 变为protected成员 仍为protected成员 不可见 基类的非私有成员变为子类的保护成员
private继承 变为private成员 变为private成员 不可见 基类的非私有成员都变为子类的私有成员

  上代码:

class AA 
{
public:
    int _a;
};
class BB :public AA
{
public:
    int _b;
};
class CC :protected AA
{
public:
    int _c;
};
class DD :private AA
{
public:
    int _d;
};

void Test1()
{
    AA a;
    BB b;
    CC c;
    DD d;
    b._a = 1;
    c._a = 2;//保护继承,父类AA成员成为子类CC的保护成员,保护成员在类外不能访问,error
    d._a = 3;//私有继承,父类AA成为子类DD的私有成员,不可见,当然也不能访问
}

  总结一下:
1. 基类的私有成员在派生类中是不能被访问的,如果一些基类成员不想被基类对象直接访问,但需要在派生类中能访问,就定义为保护成员。可以看出保护成员限定符是因继承才出现的。
2. public继承是一个接口继承,保持is-a原则,每个父类可用的成员对子类也可用,因为每个子类对象也都是一个父类对象。
3. protetced/private继承是一个实现继承,基类的部分成员并未完全成为子类接口的一部分,是 has-a 的关系原则,所以非特殊情况下不会使用这两种继承关系,在绝大多数的场景下使用的都是公有继承。
4. 不管是哪种继承方式,在派生类内部都可以访问基类的公有成员和保护成员,但是基类的私有成员存在但是在子类中不可见(不能访问)。
5. 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。

2.继承与转化: 

  • 子类对象可以赋值给父类对象(切片)
  • 父类对象不能赋值给子类对象
  • 父类的指针或者引用可以指向子类对象(多用于多态)
  • 子类的指针或者引用不能指向父类对象(但是有强制类型转化啊)
class Person
{
public :
    void Display ()
    {
        cout<<_name <<endl;
    }
protected :
    string _name ; // 姓名
};
class Student : public Person
{
public :
    int _num ; // 学号
};
void Test ()
{
    Person p ;
    Student s ;
    // 1.子类对象可以赋值给父类对象(切割 /切片)
    p = s ;
    // 2.父类对象不能赋值给子类对象
    //s = p;
    // 3.父类的指针/引用可以指向子类对象
    Person* p1 = &s;
    Person& r1 = s;
    // 4.子类的指针/引用不能指向父类对象(可以通过强制类型转换完成)
    Student* p2 = (Student*)& p;
    Student& r2 = (Student&) p;
}

这里写图片描述

派生类的默认成员函数

  派生类继承了父类,那么派生类会继承父类的六大默认成员函数吗?
1.构造函数:
  派生类不会继承父类的构造函数!
  派生类的构造函数属于合并构造函数,就是说他在执行自身的构造函数前,会先调用基类的构造函数完成它继承的基类成员的初始化,虽然你继承基类的成员,但是人家的成员初始化你得交给人家基类去做。所以说派生类执行自身的构造函数前,会先调用其基类的构造函数,如果他的基类还有父类,那么又先去调用基类的父类的构造函数,直到没有父类为止。这个调用构造函数的方式可以形象的看成一条链,也称为构造函数链。
  这里写图片描述
  派生类中如果没有定义构造函数,编译器会自动生成一个默认构造函数。但是当父类的构造函数是有参、而子类没有显示调用父类的构造函数时,就会出错,所以建议一般将构造函数都写成缺省的方式,并且在子类中显示的去调用父类的构造函数。
2.析构函数:
  析构函数和构造函数恰好相反,会先调用子类的析构函数,再去调用父类的构造函数。注意:析构函数不用显示的去调用父类的析构函数,它会自己去调用父类的析构,不想构造函数那样需要显示的去调用父类的。
  这里写图片描述
3.拷贝构造函数:
  拷贝构造函数也是构造函数,是特殊的构造函数,所以它也不会被继承,并且先调用父类的构造函数,再调用子类的拷贝构造

猜你喜欢

转载自blog.csdn.net/CY071512/article/details/80037752