继承

面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易。这样做,也达到了重用代码功能和提高执行时间的效果。
当创建一个类时,您不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类。
继承有三种继承方式:公有继承, 保护继承,私有继承。如下图所示:
这里写图片描述
一个简单的公有继承:

class Person//父类(基类)
{
public:
    Person()
    {
        cout << "Person" << endl;
    }
private:
    int _a;
};
class Student : public Person//子类(派生类)
{
public:
    Student()
    {
        cout << "Student" << endl;
    }
private:
    int _b;
};

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

继承与转换-赋值兼容规则(公有继承):

1、子类的对象可以赋值给父类(切片)
2、父类的对象不可以赋值给子类
3、父类的指针和引用赋值给子类
4、子类的指针和引用不可以赋值给父类(可以强制类型转换)

class Person//父类(基类)
{
public:
    Person()
    {
        cout << "Person" << endl;
    }
private:
    int _a;
};
class Student : public Person//子类(派生类)
{
public:
    Student()
    {
        cout << "Student" << endl;
    }
private:
    int _b;
};
void test()
{
    Person p;
    Student s;
    p = s;//子类可以赋值给父类
    //s = p;//父类不能赋值给子类
    Person* p1 = &s;//父类的指针和引用可以赋值给子类
    Person& p2 = s;
    //Student* s1 = &p;//子类的指针和引用不可以赋值给父类
    //Student& s2 = p;
    Student* s3 = (Student*)&p;//但是可以强制类型转换赋值给父类
    Student& s4 = (Student&)p;
}

我们用下图来解释切片到底是一个什么东西:
这里写图片描述

隐藏:

子类和父类中有同名成员,子类成员将屏蔽父类对成员的直接访问。(在子类成员函数中,可以使用基类::基类成员访问)–隐藏(重定义)

简单明了来说就是就是一个在基类一个在派生类中,函数名相同,不构成重写就构成隐藏。不过这里的重写下面提到,这里先这样写着。

下面我们再来说说派生类的六大默认成员函数:
在我们的派生类中,调用构造函数时,会有一个神奇的事情发生,它先会对在基类继承下来的成员进行初始化,然后再对派生类的成员进行初始化。其他四个和构造函数一样先调用父类的相对应的函数,然后派生类的,不过的是,析构函数有点区别,析构函数先对派生类的成员进行清理,在对父类的成员进行清理,毕竟栈上的规则为后进先出。
拿一个简答的构造函数举个例子吧:

#include<string>
class Person
{
public:
    Person(const char* a)
        :_a(a)
    {}
    Person(const Person& p)
        :_a(p._a)
    {}
protected:
    string _a;
};
class Student : public Person
{
public:
    Student(const char* a,int b)
        :Person(a)
        ,_b(b)
    {}
    Student(const Student& s)
        :Person(s)
        ,_b(s._b)
    {}
private:
    int _b;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值