假设我想在银河帝国中组织舰队。

class Fleet
{
    string m_commander;
    int m_totalShips;
}


class GalacticEmpire
{
    string m_coolName;
    string m_edgyTitleOfTheRuler;
    /*Problem line number1*/
}
GalacticEmpire是一个对象,它将拥有和控制仅属于我的帝国的所有内容-它将存储其数据的所有字节。

但是我的GalacticEmpire不存在于void中(从技术上讲,它确实存在),它可以控制StarSystem
class StarSystem
{
    string m_name;
    color m_starColor;
    /*Problem line number2*/
}

现在StarSystem不应该存储任何原始数据-它只需要能够指向其边界内该工作站的Fleet即可。

现在是问题。
GalacticEmpire应该如何存储Fleet以便它可以访问它们并完全从程序中销毁它们,同时StarSystem应该如何指向Fleets s以便可以对其进行迭代?
换句话说,Problem line number1Problem line number2应该是什么样子?

选项1:

问题行号1 = vector<Fleet> m_fleets
问题行号2 = vector<shared_ptr<Fleet>> m_fleets
选项2:

问题行号1 =问题行号2
= vector<shared_ptr<Fleet>> m_fleets

最佳答案

在对象设计中,这似乎是一个有趣的练习。让我们天真地尝试一下。

class GalacticEmpire
{
    std::string m_coolName;
    std::string m_edgyTitleOfTheRuler;
    std::vector<Fleet> fleets;
};

这似乎是正确的-Empire拥有自己的舰队,它们被安排在容器( vector )中,并且在这里我们不需要使用任何间接方式- vector 存储Fleet对象。

现在,让我们在StarSystem中使用 View 指针:
class StarSystem
{
    string m_name;
    color m_starColor;
    std::vector<Fleet*> fleets;
}

我们将使用StarSystem::fleets中的地址填充GalacticEmpire::fleet,乍一看似乎可行。

不幸的是,这种解决方案非常脆弱。如果Empire偶然添加了新的舰队,它将通过向GalacticEmpire::fleets vector 中添加对象来实现这一点,并使存储在StarSystem::fleets中的地址无效。不是很好!

第二次尝试:
 class GalacticEmpire
 {
    // ...
    std::vector<std::unique_ptr<Fleet>> fleets;
 };

StarSystem::fleets存储(非所有权)指针,该指针由unique_ptrGalacticEmpire::fleets s管理。这为我们解决了添加新舰队的问题-即使将新元素推送到 vector 使unique_ptr的指针有效,由所述ptrs管理的指针仍然有效。

但是,此解决方案有两个缺点:性能下降。现在可以动态创建可以直接存储在车队 vector 中的对象。访问这些文件需要间接访问,这会给性能带来沉重的损失。

另一个问题是合乎逻辑的-我们已经解决了添加新舰队的问题,但是如果舰队被撤除怎么办?我们确实需要从预期的StarSystem中清理这支舰队!

让我们考虑一下。很明显,一个StarSystem可以容纳多个舰队,但是一个舰队只能驻扎在一个StarSystem中。让我们使用以下信息:
class Fleet
{
    string m_commander;
    int m_totalShips;
    StarSystem* stationed_system;
};

我们添加指向该机队本身托管的StarSystem的指针。现在,当帝国失去一支舰队时,我们应该能够从StarSystem的舰队列表中清除该舰队。但是,我们如何找到它呢?在 vector 中迭代?这相当慢。让我们执行unordered_set,这样我们就可以在恒定时间内找到(并删除)舰队!
class StarSystem
{
    std::unordered_set<Fleet*> fleets;
};

现在,剩下的唯一事情就是确保我们在类之间引入某种类型的友元,并添加一些私有(private)和公共(public)功能,这将确保在舰队被拆除时,它也会同时从其StarSystem中被拆除。这留给读者。

关于c++ - 存储数据的对象和存储数据智能指针的对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58017846/

10-13 08:28