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

标签 c++ design-patterns reference abstract-class

我正在为数据收集 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/

相关文章:

PHP:正确使用单例模式?

c++ - C++ 迭代器是否持有对底层对象的引用?

scala - val b=a(a 是一个数组)和 val b=a.clone() 有什么区别?

c++ - 如何在发送 EM_SETCUEBANNER 消息时更改文本提示的颜色?

multithreading - 电信软件硬多线程问题的设计模式

java - 多线程java应用程序的设计模式

C++ 无法将 public const string 成员作为参数传递给同一类的成员函数

c++ - 停止共享库链接以删除未使用的类

c++ - Boost绑定(bind)并分配以将 vector 转换为字符串

c++ - 为什么我的简单 C++ 程序会出错。