栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++面向对象7:多态

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++面向对象7:多态

目录

一、虚函数

二. virtual关键词

三.纯虚函数

四.析构函数一定是虚的


一、虚函数
class Person
{
  public:
    string name;
    Person(string n): name(n){}
    void print()
    {
        cout << "Name: " << name << endl;
    }
};
class Student: public Person
{
  public:
    string id;
    Student(string n, string i): Person(n), id(i){}
    void print()
    {
        cout << "Name: " << name;
        cout << ". ID: " << id << endl;
    }
};
//子类指针可以隐含转换为父类指针
//但通过基类对象名,指针,只能访问从基类继承的对象
Person * p = new Student();//创建一个子类对象,赋给父类指针p。
p->print(); // call Person::print()? 
#include 
#include 
using namespace std;

class Person
{
  public:
    string name;
    Person(string n): name(n){}//对name赋值
    virtual void print()
    {
        cout << "Name: " << name << endl;
    }
};

class Person2
{
  public:
    string name;
    Person2(string n): name(n){}
    virtual void print() = 0; //纯虚函数
};

class Student: public Person
{
  public:
    string id;//增加了学生的学号。
    Student(string n, string i): Person(n), id(i){}
    void print() 
    {
        cout << "Name: " << name;
        cout << ". ID: " << id << endl;
    }
};

void printObjectInfo(Person & p)//可接受person对象,也可接受person的子类对象。让函数有更好的通用性。
{
    p.print();//这里面只调用父类的函数。设计函数的初衷就不成立了。如果它去调子类函数的话,万一传进来是父类的函数。那就没有这个函数了。
// 在父类里面加virtual可以改变
}

int main()
{
    {
        Student stu("yu", "2019");
        printObjectInfo(stu);  
    }

    {
        Person * p = new Student("xue", "2020");
        p->print(); //if print() is not a virtual function, different output
        delete p; //if its destructor is not virtual
    }

    // { //if you want to call a function in the base class
    //     Student stu("li", "2021");
    //     stu.Person::print();

    //     Person * p = new Student("xue", "2020");
    //     p->Person::print(); 
    //     delete p; 
    // }

    return 0;
}

调用的都是父类的函数。

加虚函数结果

 

二. virtual关键词

常规函数都是静态绑定。编译器在编译源代码的时候。他就决定了在这个位置应该执行哪个函数。

动态的绑定,他并不去决定你到底应该去执行哪个函数。在运行的时候,它根据传进来的参数判断你是什么样的函数。你应该去执行哪个函数?

父类加了虚函数,那么子类也是虚函数。不用所有的都加。

三.纯虚函数
virtual void print() = 0

虚函数是有定义的,纯虚函数是没有定义,这个函数只是一个接口。

这个类就是个纯虚类,就不能创建对象。 调用纯虚函数又不知道他干什么。一般是给父类当继承用的。

四.析构函数一定是虚的

如果不是虚函数,下面这段代码就会出问题。

Person * p = new Student("xue", "2020");
p->print(); 不是虚函数就调父类的,是虚函数就调子类的。
...
...
delete p; //if its destructor is not virtual
如果不是虚函数,就会调用父类的析构函数。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/853611.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号