C++自学笔记13(虚函数)

虚函数 

#include <iostream>
#include <string>

class Entity
{
public;
    std::string GetName(){return Entity};
};

class Player:Public Entity
{
private:
    std::string m_Name;
public;
    Player(const std::string& name):m_Name(name){};
    std::string GetName(){return m_Name};
};
int mian()
{
    Entity* e = new Entity();
    std::cout<<e->GetName()<<std::endl;

    Player* p = new Player("少杰是小白");
    std::cout<<p->GetName()<<std::endl;

    std::cin.get();
}

打印出

Enitiy

少少杰是小白

讲解代码之前先知道“std::” 是什么意思。

首先“::”表示为作用域。举个栗子AB是两个类

1、A::member就表示类A中的成员member。

2、B::member就表示类B中的成员member。

std是一个标准类存放在<iostream>中,包含cin、cout函数以及C++标准程序库中的所有标识符。

所以加上std::就是在这个命名空间下的类型,可以减少代码的奇异性。

还有一件事构造函数后的":"表示对构造函数初始化赋值。

明白以上两点再来解释代码,Entity类中GetName函数返回Entity这个名。Player类中GetName函数返回我们自己的命名。然而由于多态的问题,Player类既是Palyer类又是Entity类,有相同函数那么就会出现问题,使用Player还是Entity中的GetName呢?

#include <iostream>
#include <string>

class Entity
{
public;
    std::string GetName(){return Entity};
};

class Player:Public Entity
{
private:
    std::string m_Name;
public;
    Player(const std::string& name):m_Name(name){};
    std::string GetName(){return m_Name};
};
int mian()
{
    Entity* e = new Entity();
    std::cout<<e->GetName()<<std::endl;

    Player* p = new Player("少杰是小白");
    std::cout<<p->GetName()<<std::endl;

    Entity* ptr = p;
    std::cout<<ptr->GetName()<<std::endl; 
    std::cin.get();
}

我们实际意义上希望的是ptr指向Player类并调用其GetName函数,然而看控制台打印出

Enitiy

少杰是小白

Entity

我们想象的Player类中的p传给ptr,从而使用Player下的GetName,然而由于我们设置了Entity* ptr导致编译器优先确定了ptr属于Entity类中进而使用了Entity下的GetName,这就是原因所在。

我们在重复函数前加入“virtual”

#include <iostream>
#include <string>

class Entity
{
public;
    virtual std::string GetName(){return Entity};
};

class Player:Public Entity
{
private:
    std::string m_Name;
public;
    Player(const std::string& name):m_Name(name){};
    std::string GetName(){return m_Name};
};
int mian()
{
    Entity* e = new Entity();
    std::cout<<e->GetName()<<std::endl;

    Player* p = new Player("少杰是小白");
    std::cout<<p->GetName()<<std::endl;

    Entity* ptr = p;
    std::cout<<ptr->GetName()<<std::endl; 
    std::cin.get();
}

 此时打印台就是

Enitiy

少杰是小白

少杰是小白

我们成这个GetName这个重复函数为虚函数,为了方便代码的可读性我们在Player类中GetName加入“override”体现被复写的概念,为了方便读代码。

#include <iostream>
#include <string>

class Entity
{
public;
    virtual std::string GetName(){return Entity};
};

class Player:Public Entity
{
private:
    std::string m_Name;
public;
    Player(const std::string& name):m_Name(name){};
    std::string GetName()override{return m_Name};
};
int mian()
{
    Entity* e = new Entity();
    std::cout<<e->GetName()<<std::endl;

    Player* p = new Player("少杰是小白");
    std::cout<<p->GetName()<<std::endl;

    Entity* ptr = p;
    std::cout<<ptr->GetName()<<std::endl; 
    std::cin.get();
}

虚函数创建了一个v表,将已有的函数与重复的函数存放在一起,在不同情况下进行分配。

纯虚函数 

纯虚函数定义一个基类未实现的函数,然后强制子类去实现这个功能。我们称其为“接口”,相当于在基类(父类)建立一个模版方便调用,这在代码中十分常见。

#include <iostream>
#include <string>

class Entity
{
public;
    virtual std::string GetName() = 0;
};

class Player:Public Entity
{
private:
    std::string m_Name;
public;
    Player(const std::string& name):m_Name(name){};
    std::string GetName()override{return m_Name};
};
int mian()
{
    Entity* e = new Entity();
    std::cout<<e->GetName()<<std::endl;

    Player* p = new Player("少杰是小白");
    std::cout<<p->GetName()<<std::endl;

    std::cin.get();
}

virtual std::string GetName() = 0;

我们将其赋值为0,就说明我们建立一个纯虚函数。当建立了纯虚函数,我们必须要在子类下实现这个函数,否则我们将无法对父类Entity创建实例。

我们运行以上程序会发现报错,我们不可以对其创造实例了,但是子类Player依旧可以运行。

 我们如果让Player类中的GetName函数注释掉,就是说Palyer类没有实现纯虚函数那么

#include <iostream>
#include <string>

class Entity
{
public;
    virtual std::string GetName() = 0;
};

class Player:Public Entity
{
private:
    std::string m_Name;
public;
    Player(const std::string& name):m_Name(name){};
   // std::string GetName()override{return m_Name};
};
int mian()
{


    Player* p = new Player("少杰是小白");
    std::cout<<p->GetName()<<std::endl;

    std::cin.get();
}

我们可以看到连“少杰是小白”都打不出来了。

这就是C++中的接口,也就是纯虚函数。他可以让那个只有你实现了虚函数,才可以使用这个实例,就像是开关一样。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值