gpt4 book ai didi

c++ - 在 C++ 中安全地传递对抽象类的引用

转载 作者:可可西里 更新时间:2023-11-01 18:39:28 25 4
gpt4 key购买 nike

我正在为数据收集 Controller 开发一个应用程序。它必须与许多不同的其他设备接口(interface),这反过来可能提供不同类型和数量的数据。为此,以下层次结构是设计(有点长,但请耐心等待):

  • 信息的基本单位是数据。 Datum 本身就是一个抽象类,其后代代表不同类型的[物理]数量:温度、压力、能量、功率、继电器状态等。每个数据实例代表单个读数(在某个时刻)。

  • 数据由 Device 收集,后者又包含多个 IO。一个装置实例代表一个具体的物理数据收集设备;它的类(一个抽象 Device 类的后代)表示设备的模型和包含与其交互所需的所有特定于模型的代码,并且从中提取读数。这是通过调用虚函数 void 来完成的
    设备::更新()

  • 每个IO 实例代表一个设备收集的变量。例如,如果设备是多 channel 温度监控器,那么一个 IO 代表一个连接到设备的单个传感器。可以通过以下方式查询 IO 的值调用 IO::get_value(),返回一个 Datum

  • 最后,Node 类保留了所有附加到 Controller ,这些设备中所有 IO 的另一个列表,并提供方法一次轮询所有设备、单个设备、单个 IO 等。

这些关系(有点松散地)反射(reflect)在下图中:

Diagram of class relations

现在,对于问题本身:

在所有这一切中,有很多抽象后代的实例类必须一直传递和存储:Node 存储它的设备及其IO设备本身将自己的IO存储为好吧,数据被创建、返回、传递和销毁,设备和 IO 列表得到更新等。但目前尚不清楚如何实现所有这些传递:

  • 按值传递抽象类的实例显然是不可能的,并且即使它们不是抽象的,也可能导致对象切片。
  • 通过引用传递它们适用于函数的参数,但是呢创建和返回 Datum 实例?它们被创建为局部变量IO::get_value 方法等在返回时被销毁。此外,不可能存储引用,例如在 std::map 中。
  • 最后,传递指针是危险的。为了返回一些东西作为指针一必须在方法中分配内存,然后是调用者的业务在返回值不再使用后释放内存。在除了不方便之外,它还存在获得内存泄漏、双重释放或程序的其他部分取消引用预先存储在那里的现在为空的指针。

所以我不知道如何实现一个强大的交换系统像这样的对象,用或多或少的万无一失的方法来确保对象表现为按值传递的变量(只要它们存在,就一直存在需要,但不再需要),同时保留继承提供的鸭子类型一个通用接口(interface)。

最佳答案

使用std::unique_ptr独特的所有权和std::shared_ptr共享所有权。这使得传递指针更加安全。

std::unique_ptr 无法复制,当 unique_ptr 被销毁(例如超出范围)时,指向的对象会自动释放。相反,std::shared_ptr 可以被复制,指向的对象只有在 shared_ptr 的所有拷贝都被销毁时才会被释放。

如果您使用上述工具编写代码并使用 std::make_unique (C++14) 和 std::make_shared (C++11),很大程度上免于手动 newdelete 并避免了很多与内存相关的问题。

关于c++ - 在 C++ 中安全地传递对抽象类的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39144955/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com