当前位置: 首页 > article >正文

c++ 中虚函数和纯虚函数

一、虚函数

虚函数是用于实现多态性的一种机制。它允许通过基类指针或引用调用派生类中的重写版本。通过将函数声明为虚函数,C++ 提供了一种在运行时决定调用哪个函数的方法。

特点

语法

class Base {
public:
    virtual void show() { std::cout << "Base class show function\n"; }
    virtual ~Base() {} // 虚析构函数
};

class Derived : public Base {
public:
    void show() override { std::cout << "Derived class show function\n"; }
};
  • 使用 virtual 关键字:在基类中使用 virtual 关键字声明虚函数,派生类可以重写该函数。
  • 运行时绑定:通过基类指针或引用调用虚函数时,实际调用的是派生类中重写的版本。
  • 虚析构函数:如果类包含虚函数,通常应该有一个虚析构函数,以确保正确释放派生类的资源。

示例:

#include <iostream>

class Base {
public:
    virtual void show() { std::cout << "Base class show function\n"; }
    virtual ~Base() {}
};

class Derived : public Base {
public:
    void show() override { std::cout << "Derived class show function\n"; }
};

void display(Base* b) {
    b->show(); // 调用的是实际对象的 show 函数
}

int main() {
    Base* b = new Derived();
    display(b); // 输出:Derived class show function
    delete b; // 先调用 Derived 的析构函数,再调用 Base 的析构函数
    return 0;
}

不使用虚函数会有什么问题

不使用虚函数,无法实现运行时多态性。这意味着你不能通过基类指针或引用来调用派生类的重写方法。所有方法调用都将在编译时确定,限制了对象之间的灵活交互。

示例:

class Base {
public:
    void show() {
        std::cout << "Base class\n";
    }
};

class Derived : public Base {
public:
    void show() { // 此处不是重写,而是隐藏 注释1
        std::cout << "Derived class\n";
    }
};

void display(Base* b) {
    b->show(); // 始终调用 Base::show()
}

int main() {
    Base b;
    Derived d;
    display(&b); // 输出:Base class
    display(&d); // 仍然输出:Base class
    d.show();    // 输出:Derived class
    return 0;
}

在这个例子中,即使 display 函数接收的是 Derived 类的对象,也只会调用 Base 类的方法。实际上我想调用的是 Derived 类中的 show 方法

什么是隐藏?

隐藏是指当派生类定义了一个与基类同名的非虚函数(或静态成员函数)时,基类的同名函数会被“隐藏”,但不会被覆盖。这意味着,如果你使用基类指针或引用来调用函数,基类的方法仍然会被调用。

二、纯虚函数

纯虚函数是一种特殊的虚函数,它在基类中没有实现,只有声明。要求派生类必须重写该函数(如果派生类不实现改函数那么派生类也是个抽象类不能被实例化)。包含纯虚函数的类称为抽象类,无法直接实例化。(和 java 中的抽象方法类似)

特点

  • 语法

    class Abstract {
    public:
        virtual void show() = 0; // 纯虚函数
    };
    
  • 使用 = 0 语法:在虚函数声明后添加 = 0 表示该函数是纯虚函数。

  • 抽象类:如果一个类包含至少一个纯虚函数,该类就是抽象类,不能实例化。

  • 派生类实现:派生类必须实现所有纯虚函数才能实例化。

示例:

#include <iostream>

class Abstract {
public:
    virtual void show() = 0; // 纯虚函数
};

class Concrete : public Abstract {
public:
    void show() override { std::cout << "Concrete class show function\n"; }
};

int main() {
    // Abstract a; // 错误:无法实例化抽象类
    Concrete c;
    c.show(); // 输出:Concrete class show function
    return 0;
}

总结

  • 虚函数:提供多态性,增强代码灵活性。适用于需要不同实现但使用相同接口的场景。
  • 纯虚函数:用于定义接口,强制派生类实现特定功能。适用于设计模式、框架开发和插件架构等需要接口的场景。(java 中的抽象函数)

http://www.kler.cn/news/355691.html

相关文章:

  • Android Camera2在textureView中的预览和拍照
  • 【微信小程序_19_自定义组件(1)】
  • Leetcode 分割等和子集
  • 渗透实战 JS文件怎么利用
  • LabVIEW智能螺杆空压机测试系统
  • 机器学习篇-day08-聚类Kmeans算法
  • Java项目-基于Springboot的在线外卖系统项目(源码+说明).zip
  • 腾讯PAG 动画库Android版本的一个问题与排查记录
  • CVE-2022-26965靶机渗透
  • LLM - 配置 ModelScope SWIFT 测试 Qwen2-VL 图像微调(LoRA) 教程(2)
  • react里实现左右拉伸实战
  • YOLO11改进 | 注意力机制 | 添加双重注意力机制 DoubleAttention【附代码+小白必备】
  • 86.#include预处理命令(1)
  • 【最新华为OD机试E卷-支持在线评测】VLAN资源池(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)
  • C# 实操高并发分布式缓存解决方案
  • Git中Update和Pull的区别
  • H.264 编码参数优化策略
  • 时序数据库 TDengine 支持集成开源的物联网平台 ThingsBoard
  • 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-17
  • 【计算机网络 - 基础问题】每日 3 题(四十八)