对C++中的虚函数的说明

这篇具有很好参考价值的文章主要介绍了对C++中的虚函数的说明。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在C++中,虚函数是对多态性(Polymorphism)的一种支持。当基类指针或引用被用来调用派生类对象的成员函数时,可以通过虚函数来实现动态绑定,即根据运行时类型确定要调用的函数。

下面是使用虚函数的两个典型场景:

  1. 实现多态

如果你需要在不同的子类上调用相同名字的函数,可以将该函数定义为虚函数。这样就可以使得程序在运行时按照其具体类型来选择调用哪个版本的函数,并实现多态性。

考虑如下代码:

class Animal {
public:
    virtual void speak() {
        cout << "This animal makes a sound." << endl;
    }
};

class Dog : public Animal {
public:
    void speak() override {
        cout << "The dog barks." << endl;
    }
};

class Cat : public Animal {
public:
    void speak() override {
        cout << "The cat meows." << endl;
    }
};

int main() {
    Animal* animal1 = new Dog();
    Animal* animal2 = new Cat();

    animal1->speak(); // Output: The dog barks.
    animal2->speak(); // Output: The cat meows.

    delete animal1;
    delete animal2;

    return 0;
}

上述代码中,Animal类是一个基类,其中speak()函数被声明为虚函数。DogCat类都从Animal类派生而来,重新实现了speak()函数。在主函数中,我们分别用类型为Animal*的指针指向不同的子类对象,并调用了虚函数speak()。因为speak()是虚函数,所以调用的实际函数版本在运行时被动态地确定,从而实现了多态性。

  1. 实现动态绑定

当被重载的函数在程序运行时才能确定需要调用哪个版本时,使用虚函数非常有用。这种情况下,通过基类指针或引用调用该函数,编译器会根据其动态类型来选择调用正确的版本,也就是实现动态绑定的功能。

考虑如下代码:

class Car {
public:
    virtual void run() = 0;
};

class GasCar : public Car {
public:
    void run() override {
        cout << "Gas car runs by burning gasoline." << endl;
    }
};

class ElectricCar : public Car {
public:
    void run() override {
        cout << "Electric car runs by using battery power." << endl;
    }
};

int main() {
    GasCar myGasCar;
    ElectricCar myElectricCar;

    Car* p1 = &myGasCar;
    Car& r1 = myElectricCar;

    p1->run(); // Output: Gas car runs by burning gasoline.
    r1.run(); // Output: Electric car runs by using battery power.

    return 0;
}

上述代码中,Car类是一个抽象基类,其中run()函数被声明为纯虚函数。GasCarElectricCar类都从Car类派生而来,重新实现了run()函数。在主函数中,我们分别创建了两个不同的子类对象,并将它们的地址存储到类型为基类Car*Car&的指针和引用中。通过这些指针和引用我们调用了虚函数run()。因为run()是纯虚函数,所以编译器会根据其动态类型来选择调用正确版本的函数。

除了上述场景,还有一些其他的情况下适合使用虚函数:

  1. 实现接口

在C++中,可以通过纯虚函数来定义接口规范,然后让子类来实现这些函数。使用纯虚函数定义接口可以使得代码更加清晰和易于维护。

考虑如下代码:

class Shape {
public:
    virtual double getArea() const = 0;
};

class Rectangle : public Shape {
private:
    double width_;
    double height_;
public:
    Rectangle(double width, double height) :
        width_(width), height_(height) {}
    double getArea() const override {
        return width_ * height_;
    }
};

class Circle : public Shape {
private:
    double radius_;
public:
    Circle(double radius) : radius_(radius) {}
    double getArea() const override {
        return 3.14159 * radius_ * radius_;
    }
};

int main() {
    Shape* shapes[2] = { new Rectangle(4, 3), new Circle(2) };

    cout << "The areas of the shapes are:" << endl;
    for (int i = 0; i < 2; ++i) {
        cout << "Shape " << i + 1 << ": " << shapes[i]->getArea() << endl;
        delete shapes[i];
    }

    return 0;
}

上述代码中,Shape类是一个抽象基类,其中getArea()函数被声明为纯虚函数。RectangleCircle类都从Shape类派生而来,并重新实现了该纯虚函数。在主函数中,我们创建了一个包含两个不同形状对象的数组,并调用它们的虚函数getArea(),计算它们的面积。

  1. 实现析构函数

当类中涉及到继承时,子类中可能会定义一些新的资源。为了确保在释放基类时也能够正确地释放这些资源,可以将基类的析构函数定义为虚函数。这样,在删除通过指向基类指针或引用指向其派生类的对象时,会首先调用其派生类的析构函数,然后再调用基类的析构函数。

考虑如下代码:

class Base {
public:
    virtual ~Base() { cout << "Base destructor." << endl; }
};

class Derived : public Base{
private:
    int* ptr_;
public:
    Derived(int value) : ptr_(new int {value}) {}
    ~Derived() override {
        delete ptr_;
        cout << "Derived destructor." << endl;
    }
};

int main() {
    Base* base = new Derived(42);
    delete base;

    return 0;
}

上述代码中,Base类是一个简单的基类,其中的析构函数被声明为虚函数。Derived类从Base类派生而来,重载了该析构函数。在主函数中,我们使用类型为指向基类Base*的指针指向类型为派生类Derived的对象,并对其进行删除操作。由于Base的析构函数被声明为虚函数,因此在删除派生类对象时会先调用其析构函数,然后再调用Base类的析构函数。

需要注意的是,虚函数存在虚表(Virtual Table)和虚指针(Virtual Pointer),这些数据结构占用了额外的内存空间。如果在程序中定义过多的虚函数或虚函数的层级比较深,将可能导致性能下降。因此,在使用虚函数时也要注意其对程序性能的影响。文章来源地址https://www.toymoban.com/news/detail-491742.html

到了这里,关于对C++中的虚函数的说明的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java特征:多态性

    对象的多态性 多态性,是面向对象中最重要的概念,在Java中的体现: 对象的多态性:父类的引用指向子类的对象 格式:(父类类型:指子类继承的父类类型,或者实现的接口类型) 举例: 对象的多态:在Java中,子类的对象可以替代父类的对象使用。所以,一个引用类型变

    2024年02月12日
    浏览(32)
  • 类的多态性(JAVA)

    目录 多态  重写  向上转型 类的多态性例子:  多态的优缺点   所有的OOP语言都会有三个特征: 封装(点击可跳转) 继承(点击可跳转) 多态 多态体现: 在代码运行时,当传递不同类对象时,会调用对应类中的方法。 在java中要实现多态,必须要满足如下几个条件,缺一

    2024年02月13日
    浏览(38)
  • Android java基础_多态性

    向上转换:只能定义被子类覆写的方法,不能调用在子类中定义的方法。 运行结果: JAVA向下转换的例子,在进行对象的向下转换前,必须首先发生对象的向上转换.否则会编译不过 运行结果: 看一下,下面的例子,假如有一千个类继承了father这个类,如果我们要打印他们的信

    2024年02月22日
    浏览(41)
  • C++中的多态是什么?如何实现多态?解释一下C++中的虚函数和纯虚函数,它们的作用是什么?

    C++中的多态是什么?如何实现多态? 在C++中,多态(Polymorphism)是面向对象编程的三大特性之一,另外两个是封装(Encapsulation)和继承(Inheritance)。多态指的是允许一个接口(或一个父类引用)在多种数据类型上被实现,或者一个接口被多个不同的类以不同的方式实现。

    2024年02月19日
    浏览(60)
  • 对C++中的虚函数的说明

    在C++中,虚函数是对多态性(Polymorphism)的一种支持。当基类指针或引用被用来调用派生类对象的成员函数时,可以通过虚函数来实现动态绑定,即根据运行时类型确定要调用的函数。 下面是使用虚函数的两个典型场景: 实现多态 如果你需要在不同的子类上调用相同名字的

    2024年02月09日
    浏览(39)
  • C# 类class、继承、多态性、运算符重载,相关练习题

    34.函数重载 35.几个相同的函数  print() ,用于打印不同的数据类型。   36.基类和派生类   37.基类的初始化   38.多重继承   39.动态多态性   40.抽象性和虚方法   41.通过虚方法 area() 来计算不同形状图像的面积   42.运算符重载的实现   @www.runoob.com 

    2024年02月09日
    浏览(45)
  • 【C++庖丁解牛】面向对象的三大特性之一多态 | 抽象类 | 多态的原理 | 单继承和多继承关系中的虚函数表

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 需要声明的,本节课件中的代码及解释都是在vs2013下的x86程序中,涉及的指针都是4bytes。如果要其他平台

    2024年04月10日
    浏览(57)
  • 【Java基础教程】(十四)面向对象篇 · 第八讲:多态性详解——向上及向下转型、关键字 final与 instanceof的作用~

    掌握final 的主要作用及使用; 掌握对象多态性的概念以及对象转型的操作; 掌握instanceof 的主要作用及使用; 在Java 中 final称为终结器,在Java 里面可以使用 final定义类、方法和属性,用于表示不可变性 。 final 类:当一个类被声明为 final 时,意味着该类不能被

    2024年02月16日
    浏览(53)
  • 【C++】 为什么多继承子类重写的父类的虚函数地址不同?『 多态调用汇编剖析』

    👀 樊梓慕: 个人主页  🎥 个人专栏: 《C语言》 《数据结构》 《蓝桥杯试题》 《LeetCode刷题笔记》 《实训项目》 《C++》 《Linux》《算法》 🌝 每一个不曾起舞的日子,都是对生命的辜负 本篇文章主要是为了解答有关多态的那篇文章那块的一个奇怪现象,大家还记得这张

    2024年02月19日
    浏览(38)
  • Visual C++中的虚函数和纯虚函数(以外观设计模式为例)

    我是荔园微风,作为一名在IT界整整25年的老兵,今天来说说Visual C++中的虚函数和纯虚函数。该系列帖子全部使用我本人自创的对比学习法。也就是当C++学不下去的时候,就用JAVA实现同样的代码,然后再用对比的方法把C++学会。 直接说虚函数和纯虚函数有很多人会直接晕,但

    2024年02月15日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包