首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据复制与封装

数据复制与封装
EN

Stack Overflow用户
提问于 2013-11-02 08:20:26
回答 2查看 99关注 0票数 0

我面临的问题是如何将封装和最佳内存使用结合起来。

我无法向您展示我的代码,因此可以在广泛的示例(我希望如此)上解释它。

假设我们需要一个男人的数据库。我们只想知道关于这些人的两件事:

  1. 该男子的年龄(以出生时起计)。
  2. 他住的小镇的名字。

管理这些数据的方便和自然的方法是创建一个对象,该对象对应于一个人,并将它们存储在一个数组中:

代码语言:javascript
复制
class OMan1 {
  public:
    OMan( const int &age, const astring &t ): fAge(age), fTown(t) {}
    const int& age() const: { return fAge; }
    const astring& Town() const: { return fTown; }
    astring FullId() const: { return fTown+fAge; }
  private:
    int fAge;
    astring fTown;
}

OMan mans[N];

在这里,我们的OMans是自包含的对象,一切都很好。

除了我们克隆了数千次城镇的名字,这样浪费了内存和执行时间。

我们可以做的一个改进是为城镇名称和每个OMan存储创建独立的数组,只为城镇的年龄和一个指向城镇数组的指针:

代码语言:javascript
复制
class OMan2 {
  // same functionality as for OMan1
    int fAge;
    int fTownId;
    astring* fTowns;
}

对象仍然是自给的,sizeof(int) + sizeof(void*)比sizeof(astring)小得多,我们赢得了很多。不过,这仍然是比规模(FAge)高出2-3倍的因素,而且我们重复了fTowns数十亿次。

内存优化对我来说是至关重要的,因此我所做的是只保留fAge和fTownId,并将像OMan ()和FullId()这样的功能从OMan类转移到某些类OManDataBase:

代码语言:javascript
复制
class OMan3 {
  public:
    OMan( const int &age, const int &tid ): fAge(age), fTownId(tid) {}
    const int& age() const: { return fAge; }
    const int& TownId() const: { return fId; }
    // const astring& Town() const: { return fTown; }
    // astring FullId() const: { return fTown+fAge; }
  private:
    int fAge;
    int fTownId;
}

class OManDataBase {
  // constructor, destructor
    const int& age( const int& i) const: { return fMans[i].TownId()]; }
    const astring& Town( const int& i) const: { return fTown[fMans[i].TownId()]; }
    const astring& FullId( const int& i) const: { return Town(i)+age(i); }
  private:
    vector<OMan3> fMans;
    vector<astring> fTowns;
}

OMan3现在不是自带的对象。例如,它不知道它的全名。这意味着,如果我需要对一个人进行一些数据处理,我必须使用整个OManDataBase实例:

代码语言:javascript
复制
OBillType47 NewBillType47( const OManDataBase &db, int i ) { ... }

而不是

代码语言:javascript
复制
OBillType47 NewBillType47( const OMan &m ) { ... }

这里的封装已经中断,代码可读性明显降低。(我让Type47强调,我可以拥有许多函数,这些函数与阿曼-S一起工作,不能将它们全部包含在OManDataBase类中)。

我想知道是否有其他方法(-s)来解决数据复制问题,使对象尽可能地自我包含()。

EN

回答 2

Stack Overflow用户

发布于 2013-11-02 08:41:49

您可以创建这样的泛型类:

代码语言:javascript
复制
enum class Towns {T1 = 0, T2 = 1...}
string TownsNames[] = {"T1", "T2"...}

class OManDB 
{
   map<Towns, OMan*> m;
// OR
   map<int, Towns> m; // map by Oman ID and town

public:
   void addOMan();
   Oman getOManById(int id);
   OMan *getOManArrByTown(Towns town);
   OMan getOManTown(int omanId);
   ...
}

这样做的目的是创建一个类来保存所有记录,并为您执行所有操作,就像DB一样,您没有一个数据集和一组操作彼此分离。一切都在一个地方,您可以根据需要定义操作。

这样,您可以随意更改内部表示,您可以返回一个OMan数组--您基本上可以做任何您想做的事情,而不需要中断退出的代码。用户会知道他/她可以获得OMan,并且不需要知道存储它的字段的确切方法。您可以将它们存储在单个64位字段中(例如,如果ID只有32位,城镇是一个额外的32位字段)。它给了你自由。

更新

好,让我们暂时搁置封装,让我们来处理性能问题。理想情况下,对于每一点内存,您可以将ID和城镇的ID存储在两个不同的向量中,这将产生一个重要的优势,如果这两个字段的大小不同,并且编译器必须做一个填充。使用两个不同的数组将为您提供存储数据和避免填充的最佳选择(当然,您可以使用pack.但这是不可取的)

票数 0
EN

Stack Overflow用户

发布于 2013-11-19 15:06:29

对于这样一个问题,有一种特殊的设计模式:飞重模式。最好用它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19740179

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档