【问题标题】:Object orientation fundamental - linking results of object to another面向对象基础 - 将对象的结果链接到另一个对象
【发布时间】:2021-07-27 23:16:38
【问题描述】:

这似乎是我在 20 年前完全忘记了 comp sci 的基本原理。

如何从另一个对象链接/触发对象函数。或者我试图找到的概念的名称是什么? (如果重要,请使用 c++)

我的例子是我有一个带有蓄电池的传感器。累加器有一组时间间隔读数。它们累积值直到它们的间隔完成并将其添加到读数数组中。

我想让累加器灵活、不同的间隔、时间范围或每个传感器的累加器数量。例如。 1 小时,1 分钟间隔,1 天,每小时...

我有一个传感器类和累加器类。但是如何声明多个累加器并允许较小的时间范围读数冒泡到下一个更高的读数?

===========================

添加一个更具体的例子,因为我很难解释清楚......

传感器类中的示例函数: Sensor.addAccumulator(时间帧,间隔)

因此,第一个时间范围可以是 1 小时时间范围和 1 分钟间隔。 然后另一个累加器添加了 24 小时时间框架和 30 分钟间隔。 接下来 1 周,间隔 12 小时。

传感器将具有获取当前读数的功能,然后将其提供给累加器进行处理。

但是当积累了 1 分钟的数据时,我如何才能将其提供给下一个更高的时间范围?

我可以只为每个累加器提供读数,但计算变得多余,而且它在微控制器上。

=========

如果我有一个高性能设备,我会将值转储到时间序列数据库中,并使用数据保留策略对旧数据进行下采样。

【问题讨论】:

  • 所以“累加器”被声明为“传感器”的成员元素?
  • 然后“累加器”作为一个类有自己的定义?
  • 如果你想发布一个sn-p,也许我们可以把它标记为“C++”。
  • 是的,我创建了一个传感器类,它具有从传感器获取实时读数并将其提供给累加器类进行计算的功能。
  • 我现在只有一个累加器,因为我不知道如何链接更高级别的累加器。基本上,更高级别的数据是对数据进行下采样,但我试图避免在每个时间范围内对实时数据进行冗余重新计算。

标签: c++ oop


【解决方案1】:

你需要做的是有一个累加器的链表。

那么您将拥有自己的 class Sensor,但作为会员,您将拥有一个元素

mll_Accumulator *accumulator;

那是链表的第一个元素。回想一下,要创建链表,您必须有一个类型声明,其中包含一个元素,该元素是指向同一类型对象实例的指针。

然后,如果您有mll_Accumulator *next;,那么要通过以mll_Accumulator seed = new mll_Accumulator; 开头的链接列表访问它,您可以通过使用seed->next 取消引用成员元素或使用seed->next->next 迭代来访问它,然后您将通过调用或迭代链表到seed->next 为空的末尾并调用seed->next = new mll_Accumulator; 来延长链表,否则您可能会查看任意内存位置。

我在想mll_- 作为前缀的命名约定可以读作“成员链表”。但这可能就是它的本质:一个链表。

【讨论】:

  • 旁注:请记住,C++ 有一个 std::list(定义为实现它的唯一直接方法是双向链表)和 std::forward_list(几乎可以肯定是一个单链表) -在。很少需要滚动你自己的链表。也就是说,std::deque 可能是此答案所描述的工作的更好数据类型。
  • @user4581301 总是有空间给另一个答案。
  • 我不太确定要写答案的问题是什么。我只是想指出,您的建议并不像听起来那么难实施。工具已经存在。
【解决方案2】:

我在评论中表达了我对Accumulator 设计灵活性的担忧,但将其放在一边——如果您确实想要实现分层Accumulators,我认为是在OOP 方面最好的选择是翻转你的课程——不要有一个包含Acccumulators的Sensor,而是有一个包含一个抽象DataSourceAccumulators——DataSource可以 成为Sensor 本身,或另一个Accumulator

DataSource 接口提供了一个.getValues(size_t count) 函数,对于Sensor 仅支持.getValues(1) 读取硬件并返回测量值,对于Accumulator 读取那么多存储值并返回它们. (所以你需要一个std::vector<ValueType> 作为返回类型,即使是Sensor。或者你可能想让DataSource 对值列表求和并返回结果。这样你就可以将返回类型保持为单个 ValueType 值,而不是 std::vector。)

当将另一个Accumulator 作为DataSource 时,“父级”Accumulator 会计算出自己的frequency 是子级Accumulator 自己的interval 的倍数,并读取很多来自DataSource 每个interval 的值。因此,如果 10 分钟间隔 Accumulator 从 1 分钟间隔 Accumulator 拉动,则其 frequency 为 10,当它被触发时,它会在其 DataSource 上调用 DataSource.getValues(10)。从 2 分钟间隔 Accumulator 拉取,它将每 10 分钟调用一次 .getValues(5)

如果您保留Accumulators 的主std::vector 并对其进行排序,以便最短间隔的总是首先更新,那么每当他们被轮询时,他们就会为他们的父母准备好数据。

这打破了push is better than pull 的一些争用,但它更好地表达了层次结构中Accumulators 之间的关系。每个Accumulator 只能有一个DataSource,并且只需要处理从该源检索数据。给定的Accumulator 可能会被 多个 父母轮询(想想 2 分钟、3 分钟和 7 分钟间隔 Accumulators,所有读取都从相同的 1 分钟间隔 DataSource ),而Accumulator 的孩子不必知道或关心这种复杂性。

【讨论】:

    猜你喜欢
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    • 2023-01-08
    • 2019-02-22
    • 1970-01-01
    • 2015-01-17
    相关资源
    最近更新 更多