c++ - 存储数据的对象和存储指向数据的智能指针的对象
问题描述
假设我想在我的银河帝国中组织舰队。
class Fleet
{
string m_commander;
int m_totalShips;
}
class GalacticEmpire
{
string m_coolName;
string m_edgyTitleOfTheRuler;
/*Problem line number1*/
}
GalacticEmpire
是一个将拥有和控制仅属于我的帝国的一切的对象-它将存储其数据的所有字节。
但是 myGalacticEmpire
不存在于 void 中(我的意思是技术上它确实存在),StarSystem
它控制着 s。
class StarSystem
{
string m_name;
color m_starColor;
/*Problem line number2*/
}
NowStarSystem
不应该存储任何原始数据 - 它只需要能够指向Fleet
s 在其范围内的那个站点。
现在的问题。
应该如何GalacticEmpire
存储Fleet
s 以便它可以访问它们并销毁它们(完全来自程序),同时StarSystem
应该如何指向Fleets
s 以便它可以迭代它们?换句话说,应该Problem line number1
是Problem 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 拥有自己的舰队,它们被安排在容器(向量)中,我们不需要在这里使用任何间接方式——向量存储Fleet
对象。
现在,让我们使用视图指针StarSystem
:
class StarSystem
{
string m_name;
color m_starColor;
std::vector<Fleet*> fleets;
}
我们将填充StarSystem::fleets
来自 的地址GalacticEmpire::fleet
,乍一看似乎有效。
不幸的是,这个解决方案非常脆弱。如果Empire
碰巧添加了新的舰队,它会通过将对象添加到GalacticEmpire::fleets
向量来做到这一点,并使存储在StarSystem::fleets
. 不是很好!
第二次尝试:
class GalacticEmpire
{
// ...
std::vector<std::unique_ptr<Fleet>> fleets;
};
并存储由s ofStarSystem::fleets
管理的(非拥有的)指针。这解决了我们添加新队列的问题——即使将新元素推送到向量 ivalidate 指向s 的指针,由所述 ptrs 管理的指针仍然有效。unique_ptr
GalacticEmpire::fleets
unique_ptr
但是,此解决方案有两个缺点:您会失去性能。现在可以动态创建可以直接存储在车队向量中的对象。访问这些需要间接访问,这一切都会对性能造成严重影响。
另一个问题是合乎逻辑的——我们已经解决了添加新车队的问题,但是如果车队被移除了怎么办?我们确实需要从预期的 StarSystem 中清理这支舰队!
让我们想一想。很明显,一个StarSystem
可以承载多个舰队,但一个舰队只能驻扎在一个单一的内部StarSystem
。让我们使用这些信息:
class Fleet
{
string m_commander;
int m_totalShips;
StarSystem* stationed_system;
};
我们将指向 StarSystem 的指针添加到该舰队本身托管。现在,当一个帝国失去它的一支舰队时,我们应该能够从驻扎在星际系统的舰队列表中清除该舰队。但是,我们如何找到它?在向量中迭代?这个比较慢。让我们改用 unordered_set,这样我们就可以在恒定时间内找到(并删除)一个舰队!
class StarSystem
{
std::unordered_set<Fleet*> fleets;
};
现在,唯一剩下的就是确保我们在类之间引入某种类型的友谊,并添加一些私有和公共功能,以保证无论何时移除一个舰队,它也会从它的 StarSystem 中移除。这是留给读者的。
推荐阅读
- python - 使用 python argschema 解析位置 cli args
- automation - 从 Access 到文本框输入字母数字值 - VBScript - Powerbuilder
- vba - vba 提取期间的高内存利用率问题
- cloud-foundry - 无法使用 cli 登录 Cloud Foundry
- go - 在 Go 中加载地图元素是否意味着复制?
- node.js - HTML Pdf转换器在windows中工作正常,但在linux中使用nodejs?
- python - 我想从一个 Odoo 实例(单击按钮)重定向到另一个 Odoo 实例。另外,想在登录后在第二个实例上打开向导
- python - 如何对 COSE 签名的消息进行编码?
- c# - 如何消除控制台窗口边缘的颜色异常?
- pentaho - 检查复制数据 Pentaho