【问题标题】:Better for complex data members to be dynamically or statically allocated?更适合动态或静态分配复杂数据成员?
【发布时间】:2013-12-05 19:25:23
【问题描述】:

我正在考虑一个问题,但无法确定这两个选项中的“更好”。它归结为决定一个复杂的数据成员(即,不是原语)应该是一个指针还是一个值。 (注意,我已经看到很多关于数据成员的指针与引用的问题,但没有关于指针与值的问题)我正在权衡的最大的事情是

  1. 数据成员的生命周期(无论它是否在其所有者的整个生命周期中都存在)。
  2. 在它确实持续整个生命周期的情况下,减少内存碎片。

考虑以下代码:

class PlayerStatistic
{
    int m_MaxValue;
    int m_CurrentValue;
    // And many other things that round out a player statistic
}

class PlayerStatisticManager
{
    //While in this case, it may be better to store stats as a list of some kind and
    //identify them by a StatId or something, for this example, I'm declaring them 
    //individually.
    PlayerStatistic* m_pHealth;
    //OR
    PlayerStatistic m_Health;

    // And many more statistics.
}

在上面的例子中,每个玩家总是有生命值。他们的健康统计总是 StatisticManager 的生命周期,而后者又总是玩家的生命周期。

如果不是这样,我更喜欢指针,这样NULL 可以指示对象不存在(这对于并非所有玩家都有的统计数据可能更好)。

但是,由于情况并非如此,我认为我宁愿将其存储为值,以便减少较大的内存分配,而不是许多小的内存分配。

我的想法是正确的,还是有什么我没有考虑的?

编辑 - 我选择的词(“指针与值”)很差。我的意思是其中一个答案澄清了:

你在这里指的是天气,最好有 mHealth 静态或动态分配;

此外,在这种情况下,我知道健康的寿命就是玩家的寿命,所以我的问题基本上归结为记忆。静态分配数据成员以减少分配,而不是进行一次大分配(当 Player 更新时)是否更好的内存管理。

【问题讨论】:

  • 根据项目的大小,您可能还需要考虑,如果您使用指针而不是值,则在声明使用它的类时,整个类不需要在范围内,即PlayerStatisticManager在你的例子中。这可以减少编译依赖,这在大型项目中可能会缩短编译时间。出于这个原因,我更喜欢指针(准确地说是某种智能指针)。
  • 如果一个类中的数据是可选的,因为同一类的 2 个成员属于明确的不同类别(例如棒球中的投手和击球手),您可能需要考虑使用继承.您将拥有一个非常基本的球员类,然后从它继承来制作投手和击球手类,例如
  • @user904963,如果我打算以这种方式使用继承,我会同意。我在考虑更多关于数据驱动差异的东西,例如 RPG 中的类(某些类的特殊能量统计或其他东西)。

标签: c++ pointers memory datamember


【解决方案1】:

您需要考虑的一件事是您将如何使用这些数据。无论您是需要通过各种例程对其进行更改,还是在大多数流程中进行简单的监控。

如果您确实需要更改它并将更改公开给其他例程,最好通过引用传递它,在这种情况下指针将是更好的解决方案。

另一方面,如果是一个简单的值,需要监控并且不经常更改,我建议通过值传递,尤其是监控不经常发生。

就您而言,以下是我的分析: 1. 发生战斗等事件时,玩家的健康可能会频繁变化。在这种情况下,数据最好通过引用传递。 2. 玩家健康状况在非战斗状态时很少被少数进程监控,例如用户查询健康值时。在这种情况下,数据最好按值传递,因此对值的意外更改不会影响对象实例本身。

就我个人而言,我会在 PlayerStaticManager 中使用指针。这提供了在不同场景中传递值或引用的选项。如果您需要通过引用传递,请传递指针。如果您需要按值传递,请复制内容,将其传递并忘记副本。

希望这会有所帮助。

【讨论】:

  • 我认为我选择使用的词可能令人困惑。 Pandrei 的回答澄清了我的意思,我编辑了我的问题以澄清我关心的问题——即内存碎片。
  • Pandrei 实际上将指针误认为与值相同。按指针是按引用的一种形式,因为您将在内存中修改数据本身。通过价值手段复制,传递。显然通过指针不是这样的情况。要回答“新”问题,我会选择静态分配。像 mHealth 之类的值,尤其是对于玩家而言,会从玩家创建到玩家被完全删除之前一直存在。静态对我来说更有意义。
【解决方案2】:

仅当成员的生命周期与包含对象的生命周期不同时才使用指针。

【讨论】:

  • 这是我倾向于的思路。我只是想确定为什么,尤其是考虑到内存管理和碎片。
  • 我要补充一点,这是有利的唯一原因是因为它通过隐式内存管理来帮助防止碎片。 newdelete 不使用时不能乱用。
【解决方案3】:

我认为您有些混淆了:“按引用”或“按值”是指您如何将参数传递给函数。首选按指针或按值,因为在这种情况下,只传递指向内存位置的指针;例如,对于结构,所有成员都被复制到堆栈中 - 增加了开销。

您在这里指的是天气,最好静态或动态分配mHealth;这是一个设计问题,取决于应用程序。两种方式都很好 - 但没有最终更好的解决方案 - 这取决于....

【讨论】:

  • 是的。这就是我的意思(你的第二段)。我在上面澄清了我的问题。
猜你喜欢
  • 2016-06-27
  • 1970-01-01
  • 1970-01-01
  • 2013-05-03
  • 2012-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多