C++ 虚函数实战示例详解

 更新时间:2025年07月16日 10:24:45   作者:W1E  
C++抽象基类cap_ops定义设备操作接口,支持多态,统一管理摄像头、传感器等设备,包含线程控制与资源管理方法,建议使用智能指针和日志,便于扩展和维护,本文给大家介绍C++ 虚函数实战,感兴趣的朋友一起看看吧

你这段代码展示了一个典型的 C++ 面向对象设计框架,特别适合用于设备驱动接口、摄像头/传感器采集接口、或嵌入式系统中的数据流采集模块。

下面我们来逐层讲解你这个代码在干什么

✅ 一、抽象基类 cap_ops

class cap_ops {
public:
    virtual ~cap_ops() {};
    virtual int init() { return 0; }
    virtual int open(streamCb callback) = 0;
    virtual int start() = 0;
    virtual int stop() = 0;
    virtual int close() = 0;
    virtual int custom_ioctl(int type, void *input, void *output) {
        return 0;
    }
};

✨ 功能:

这是一个纯虚基类(抽象接口),表示“某种可采集的设备操作集合(capture operations)”。

💡 特点说明:

成员含义
virtual ~cap_ops()虚析构函数,保证子类析构时资源能正确释放
init()可选初始化操作,提供默认实现
open()start()stop()close()纯虚函数(= 0),必须由子类实现
custom_ioctl()自定义控制命令(提供默认空实现)

✅ 二、具体子类 Device_Info 实现接口

class Device_Info : public cap_ops {
public:
    Device_Info();
    ~Device_Info();
    int open(streamCb callback);
    int start();
    int stop();
    int close();
    // 拓展的功能函数
    int get_soc_temp(void);
    int get_mcu_temp(void);
    int get_cpu_use_rate(void);
    int get_ram_use_rate(void);
    int get_rgb_frame_rate(void);
    int get_dtof_frame_rate(void);
    int get_point_cloud_rate(void);
    Version_ID_t get_soc_app_version(void);
    Version_ID_t get_soc_kernel_version(void);
    Version_ID_t get_mcu_version(void);
    Version_ID_t get_soc_Daemon_proc_version(void);
    Version_ID_t get_soc_slam_alo_version(void);
    int get_sensor_dtof_temp(void);
private:
    void device_info_capture(void *arg);
    int fd = -1;                        // 设备文件描述符
    std::atomic<bool> capture;         // 控制采集线程状态
    streamCb callback;                 // 数据回调函数
    std::thread thread;                // 采集线程
    std::mutex syncMutex;              // 用于线程同步
    std::condition_variable syncCond;  // 用于线程同步
};

✨ 作用:

这个类是对 cap_ops具体实现,是一个实际的“设备信息采集类”。

你可以这样理解:

cap_ops 是“接口”,Device_Info 是“具体设备的实现”。

✅ 三、你这个类的用途总结

这个类典型用法如下图:

cap_ops* dev = new Device_Info();
dev->open(my_callback);
dev->start();
// 后续处理……

也可以在设备框架中注册:

std::vector<cap_ops*> device_list;
device_list.push_back(new Device_Info());

这样你可以实现多种设备的统一抽象管理,比如不同摄像头、IMU、温度传感器、RGBD 模块等都继承 cap_ops

✅ 四、线程相关部分说明

类中有如下成员:

std::thread thread;
std::mutex syncMutex;
std::condition_variable syncCond;
std::atomic<bool> capture;

这些是典型的 采集线程控制器,说明这个类很可能:

  • start() 中创建一个采集线程
  • 在线程中读取设备数据(比如通过 I²C、USB、文件系统等)
  • 然后通过 callback 反馈数据出去
  • stop() 中停止线程
  • close() 中释放资源

✅ 五、你应该怎么使用它?

例如你可以这么写:

Device_Info device;
device.open(my_stream_callback);  // 注册回调
device.start();                   // 启动采集线程
// … 等待采集 …
device.stop();                    // 停止采集
device.close();                   // 关闭设备

✅ 六、补充建议

如果你是这个代码的维护者/开发者,可以考虑做以下改进:

  • 使用 std::unique_ptr<cap_ops> 管理资源,避免泄漏;
  • open() 函数建议加参数检查(回调不能是空);
  • 加入日志宏,便于跟踪设备采集状态;
  • 若涉及多个设备,可做一个 Device_Manager 统一管理不同 cap_ops 子类。

如果你想调试这个类的线程问题、数据采集流程、或某个 get_cpu_use_rate() 等函数实现,我也可以进一步帮你分析。欢迎贴上代码继续交流。

非常好!作为 C++ 初学者,你现在接触的是 C++ 面向对象编程的核心概念之一:抽象类 和 虚函数机制。你这段代码非常典型,下面我会用通俗易懂的方式来讲清楚你看到的每一部分,帮助你彻底理解这个“接口类”的作用。

✅ 一、这段代码是干什么的?

class cap_ops {
public:
    virtual ~cap_ops() {};
    virtual int init() { return 0; }
    virtual int open(streamCb callback) = 0;
    virtual int start() = 0;
    virtual int stop() = 0;
    virtual int close() = 0;
    virtual int custom_ioctl(int type, void *input, void *output) {
        return 0;
    }
};

这是一个 抽象接口类(英文通常叫 interface base class),意思是:

定义了一组功能接口(函数名和参数),但不关心具体怎么实现。由“子类”去继承并实现这些功能。

它的设计目标就是:“统一接口,便于扩展”,常用于大型项目的架构设计中。

✅ 二、逐句解释代码

class cap_ops { ... };

定义了一个类,名字叫 cap_ops,可以理解为:“捕获操作(Capture Operations)”。

virtual ~cap_ops() {};

这是一个 虚析构函数,目的是为了让你在通过基类指针释放子类对象时,能正确析构子类资源

cap_ops* p = new Device_Info();  // 派生类对象
delete p;  // ✅ 若析构函数是虚函数,才能正确释放子类资源

面试常考!

virtual int init() { return 0; }

  • 这是一个虚函数,有默认实现,子类可以选择重写(override)。
  • 比如有些设备需要初始化,有些不需要,这里提供默认实现 return 0(代表成功)。

virtual int open(streamCb callback) = 0;

这个 = 0 表示这是一个纯虚函数,意思是:

这个函数必须由子类实现,否则这个类不能被实例化。

这种函数通常用来定义“接口”,而不提供实现。例如打开设备、设置回调等。

virtual int start() = 0;stop()close()

也是纯虚函数,表示所有继承 cap_ops 的子类都必须实现这几个函数,否则编译不过。

virtual int custom_ioctl(...) { return 0; }

这是一个带有默认实现的虚函数,代表设备的“自定义命令接口”(很像 Linux 驱动中的 ioctl),
子类可以选择重写它,也可以使用默认实现。

✅ 三、为啥要这样设计?(举个栗子🌰)

假设你现在要支持三种设备:

  • 摄像头(Camera)
  • 麦克风(Microphone)
  • 温度传感器(TempSensor)

它们的功能不同,但“打开/启动/停止/关闭”的操作流程很相似。

你可以统一写一个接口类 cap_ops,然后不同设备继承它:

class Camera : public cap_ops {
    int open(streamCb cb) override { ... }
    int start() override { ... }
    int stop() override { ... }
    int close() override { ... }
};
class Microphone : public cap_ops {
    // 实现类似函数
};

然后你就可以统一管理这些设备了,比如用一个数组:

std::vector<cap_ops*> devices;
devices.push_back(new Camera());
devices.push_back(new Microphone());
for (auto dev : devices) {
    dev->open(my_cb);
    dev->start();
}

你无需关心它到底是哪个设备,反正都符合接口规范!

这就是面向对象中最强大的思想之一:多态(Polymorphism)

✅ 四、总结:这段代码学到了什么?

概念解释
virtual表示虚函数,可以被子类重写
= 0表示纯虚函数,子类必须实现(抽象接口)
抽象类有至少一个纯虚函数的类,不能直接实例化
多态父类指针调用子类实现的函数(通过 virtual 实现)
接口设计抽象类定义规范,子类实现具体功能
虚析构函数用父类指针删除子类对象时,必须加 virtual 保证资源释放完整

✅ 如果你想更深入了解

我可以为你写一个完整的例子,展示这个接口类和子类如何协作工作,包括:

  • 如何 new 一个子类对象;
  • 如何通过 cap_ops* 来调用接口;
  • 如何启动采集线程、回调函数等;

只需要说一声“写个完整 demo 给我”,我马上就给你写 🧠💻。

你已经迈出了 C++ 面向对象的关键一步,很棒了!继续保持!💪

到此这篇关于C++ 虚函数实战介绍的文章就介绍到这了,更多相关C++ 虚函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于MATLAB神经网络图像识别的高识别率代码

    基于MATLAB神经网络图像识别的高识别率代码

    今天小编就为大家分享一篇关于基于MATLAB神经网络图像识别的高识别率代码,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • C语言图书管理系统简洁版

    C语言图书管理系统简洁版

    这篇文章主要为大家详细介绍了C语言图书管理系统简洁版,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • C++实现PatchMatch图像修复算法

    C++实现PatchMatch图像修复算法

    这篇文章主要介绍了C++实现PatchMatch图像修复算法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • C语言数据的存储超详细讲解下篇浮点型在内存中的存取

    C语言数据的存储超详细讲解下篇浮点型在内存中的存取

    使用编程语言进行编程时,需要用到各种变量来存储各种信息。变量保留的是它所存储的值的内存位置。这意味着,当您创建一个变量时,就会在内存中保留一些空间。您可能需要存储各种数据类型的信息,操作系统会根据变量的数据类型,来分配内存和决定在保留内存中存储什么
    2022-04-04
  • C++的静态成员变量和静态成员函数详解

    C++的静态成员变量和静态成员函数详解

    这篇文章主要为大家介绍了C++的静态成员变量和静态成员函数,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • C语言数据的存储超详细讲解中篇练习

    C语言数据的存储超详细讲解中篇练习

    使用编程语言进行编程时,需要用到各种变量来存储各种信息。变量保留的是它所存储的值的内存位置。这意味着,当您创建一个变量时,就会在内存中保留一些空间。您可能需要存储各种数据类型的信息,操作系统会根据变量的数据类型,来分配内存和决定在保留内存中存储什么
    2022-04-04
  • C++判断一个点是否在圆内的方法

    C++判断一个点是否在圆内的方法

    这篇文章主要为大家详细介绍了C++判断一个点是否在圆内的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • C++11新特性之lambda、包装器详解

    C++11新特性之lambda、包装器详解

    lambda表达式是一种匿名函数对象,可以定义在函数内部,用于定义轻量级的局部小函数,本文给大家介绍C++11新特性之lambda、包装器的相关知识,感兴趣的朋友跟随小编一起看看吧
    2026-02-02
  • C语言中回调函数的含义与使用场景详解(2)

    C语言中回调函数的含义与使用场景详解(2)

    这篇文章主要为大家详细介绍了C语言中回调函数的含义与使用场景,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C语言求质数的几种简单易懂方式

    C语言求质数的几种简单易懂方式

    这篇文章主要介绍了C语言求质数的几种简单易懂方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12

最新评论