如何在不丢失OOP的情况下让对象在内存中连续?

时间:2017-12-04 16:37:14

标签: c++ oop memory memory-management

考虑一个代码,其中我们有一个国家/地区列表,其中包含包含街道列表的城市列表。给定City中的每个Country包含完全相同数量的Street s(nbStreetsPerCity),并且每City个街道的数量随时间不变。< / p>

class Street
{

};

class City
{
   // Attribute
   std::vector<Street> Streets;

   // getter
   Street& getStreet(int street_index) {return Streets[street_index];}
   // More stuff 

};

class Country
{
   // Attribute
   std::vector<City> Cities;

   // getter
   City& getCity(int city_index) {return Cities[city_index];}

   // More stuff 

};

我必须遍历每个Street,当我有很多Street和很少City时这个过程非常快,但是当我有很多City时,这个过程很慢几乎没有Street s

的人

使用此类代码,给定Street的所有City的{​​{1}}在内存中不连续。出于性能原因,我想尝试一个代码,其中给定Country的所有Street s在内存中是连续的。在没有破坏部分面向对象编程的情况下,我想不出让所有Country连续存储的方法。

Street

使用这样的代码,给定国家/地区的所有class Street { }; class Country { // Attribute std::vector<Street> Streets; int nbStreetsPerCity; // getter City getStreet(int city_index, int street_index) { Streets[city_index*nbStreetsPerCity + street_index] }; // More stuff }; 在内存中是连续的,但是,我丢失了Street对象,因此失去了OOP的优势。

有没有办法让所有街道在记忆中连续而不失去OOP的优势?

非常欢迎一个非常简单的例子!

2 个答案:

答案 0 :(得分:2)

这样做的方法是拥有一个包含街道矢量的“StreetManager”。然后,您的城市和国家/地区包含街道管理员所持街道的引用。

当我说'引用'时,这些可能只是索引或某些id或其他任何允许根据您的读/写要求进行查找的内容。
通过读/写要求,我指的是在向量编辑时可能会破坏引用,在向量移除时会破坏索引,而id将需要id的映射 - &gt;由经理维护的指数。

您所在城市/国家/地区的函数'getStreets'只需将索引/ ID传递给经理并返回结果。

要记住的重要一点是,尝试编辑管理器中的Streets会导致所有引用被破坏。

答案 1 :(得分:0)

这可以用于这种扇出的最低级别,但这将是一个巨大的痛苦,有一件事你必须知道一个城市在分配之前有多少街道,而另一个街道将有另一个是一个大小相等的对象(意思是街道名称的最大长度)。

您将使用city对象末尾的count和zero-size数组替换向量,而不是使用new分配,您必须使用malloc或其他一些分配器,然后使用placement new将城市初始化为那个缓冲区。然后,您将浏览steets列表并将它们复制到实际在城市对象之后退出的数组中。

像我说的那样,它可以做到,但是很痛苦。在走这条路之前,确保你确实有理由做些类似的事情。