c++(八)、继承与多态(二)

一、抽象类与动态类型转换

1、访问控制属性

类的定义中有public、private和protected三个关键字,其中private关键字说明类中成员为私有成员,只能在类内的函数访问;public成员为公有成员,可被任何其他类访问,protected关键字是保护属性,保护属性的数据或函数可被派生类成员访问。

class A
{
public:
    int i;
protected:
    int j;
private:
    int k;
};

class B : public A//公有继承
{
public:
    void display()
    {
        std::cout << i << std::endl;//ok;
        std::cout << j << std::endl;//ok;
        std::cout << k << std::endl;//error

    }
};


int main()
{
    A a;
    td::cout << a.i << std::endl;//ok;
    std::cout << a.j << std::endl;//error;
    std::cout << a.k << std::endl;//error
    return 0;
}

继承分为公有继承、私有继承和保护继承;

//基类
class A
{};

//公有继承
class B : public A
{};

//私有继承
class C : private A
{};

//保护继承
class D : protected A
{};

三种继承的区别:

//公有继承                      对象访问    成员访问
public    -->  public              Y         Y
protected -->  protected           N         Y
private   -->  private             N         N

//保护继承                      对象访问    成员访问
public    -->  protected           N         Y
protected -->  protected           N         Y
private   -->  protected           N         N

//私有继承                      对象访问    成员访问
public    -->  private             N         Y
protected -->  private             N         Y
private   -->  private             N         N

2、抽象类与纯虚函数

当类太抽象以至于无法实例化就叫做抽象类。抽象类不能实例化(创建对象)。

当基类中的函数要求子类实现它时,此函数叫做抽象函数或纯虚函数。

//基类
class Bike
{
public:
    virtual string getBikeName() = 0;//抽象函数/纯虚函数;
};

class MountainBike : public Bike
{
public:
    string getBikeName//子类将其实例化;
    {
        return "MountainBike";
    }
};

包含纯虚函数(抽象函数)的类叫做抽象类。上述例子中Bike类为抽象类,不能实例化对象。

3、动态类型转换

动态类型转换使用:dynamic_cast运算符。

作用:a、沿继承层级向上、向下及侧向转换到类的指针和引用。

转指针失败时返回nullptr,转引用失败则抛出异常。

//基类
class Bike
{
public:
    virtual string getBikeName() = 0;//抽象函数/纯虚函数;
};

class MountainBike : public Bike
{
public:
    string getBikeName()//子类将其实例化;
    {
        return "MountainBike";
    }
};

class RacingBike : public Bike
{
public:
    string getBikeName()
    {
        return "RacingBike";
    }

};

void print(Bike &bike)
{
    std::cout << "the bike is " << Bike.getBikeName() << std::endl;
    Bike* p = &bike;
    MountainBike* c = dynamic_cast<MountainBike*>(p);//动态类型转换为子类;

    if (c != nullptr)
    {
        std::cout << "the bike is" << c->getBikeName() << std::endl;
    }
}

4、上转和下转

将派生类型指针赋值给基类类型指针为上转;反之为下转。

上转可不使用dynamic_cast而隐式转换;

下转必须显式执行。

上面的方法简称为:父上,子下;上转隐,下转显。

之所以有上述规则,是因为可将派生类对象截断,只使用继承来的信息,但不能将基类对象加长,无中生有变出派生类对象。

5、typeid(运行时查询类型的信息)

运算符typeid返回一个type_info对象的引用,typeid(TYPE).name()返回实现定义。

#include <iostream>
#include <typeinfo>
A a{};

auto& t = typeid(a);
if(typeid(A) == t)
{
    std::cout << "t has type " << t.name() << std::endl;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值