gpt4 book ai didi

c++ - 实现存储类来存储某个类的多个实例

转载 作者:太空宇宙 更新时间:2023-11-04 11:47:00 26 4
gpt4 key购买 nike

我们有一个存储类,Person类,定义如下:

class Person
{
public:
string m_name;
string m_address;
string m_phone_number;
};

我们希望有一个存储类,PersonPool,用于存储所有 Person 的实例。

类(class)要求:

  1. 应该包含所有 Person 的实例。
  2. 应提供将 Person 添加到池中的方法。
  3. 应提供快速访问方法以按地址
  4. 删除人员
  5. 应该为按地址
  6. 的人提供 快速非常量 setter/getter

我们建议以下类(class):

class PersonPool
{
public:
void add_person(const Person& p) { m_persons.insert(p.m_address, p); }
bool person_exists(string address) { return m_persons.has_key(address); }
Person& get_person(string address) { return m_persons[address]; }
void remove_person(string address) { m_persons.erase(address); }

private:
map<String,Person> m_persons; ///> key: person address; value: Person's instance
};

使用示例

假设我有这段代码:

  1. PersonPool p_pool;
  2. 人员 p1;
  3. p1.m_address = "x";
  4. p_pool.add_person(p1);
  5. Person& p2 = p_pool.get_person("x");
  6. p2.m_address = "y";
  7. p_pool.get_person("y");

问题

例子中的第6行修改了Person的地址。
当我想根据新地址(“y”)得到一个Person时,PersonPool将无法返回这个Person
它“不知道”地址已被修改,仍然保留旧地址“x”作为该 Person 实例的键。

PersonPool 增强建议:

  1. map 的关键不应该是地址。
    问题:
    • 正确的键是什么?请记住,我们需要通过地址快速访问。
    • 如果我们选择的新 key 也被 Person 的用户修改(甚至 m_name 也可能被修改)怎么办
  2. 将函数添加到PersonPool:
    void update_person(string old_address, string new_address)
    问题:
    • 丑陋。用户应该不要因为我的糟糕设计而烦恼。
    • 如果用户不使用这个方法怎么办
  3. 仅提供 const getter。对存储在 PersonPool 中的 Person 的任何修改都必须使用 PersonPool 提供的函数来完成
    问题:
    • 违反了类(class)要求。我们需要非常量 getter
    • 即使我们放弃该要求,也意味着我们必须在 PersonPool 中复制 Person 接口(interface)。我们当然不想那样做。

问题:

你能想到一个更好的 PersonPool 实现吗?是否可以调整我的建议并解决这个问题。

感谢您的宝贵时间!

最佳答案

我真的不知道这是不是学术练习。无论如何,很难确定哪种特定的存储实现将为您提供最佳性能。这将取决于许多因素,包括(但不限于):

  • 数据集的大小(有多少人)
  • 数据集的内容(字符串的格式和大小)
  • 您正在使用的特定库的效率
  • 典型用法(优化查找与更新)

我会采取的方法是设计类接口(interface)以满足所有使用要求,构建一些简单的性能测试,然后开始比较不同存储实现的相对性能。从最简单的实现开始,如果需要,继续进行更复杂的优化(避免过早优化!)。

这就是封装的好处:您可以自由更改内部实现细节,而不会影响接口(interface)的用户。

此外,使用地址作为唯一键似乎也行不通。如果您实际上是在为真实世界的数据建模,难道不止一个人有相同的地址(或姓名或电话号码)是可能的吗?我可能还会使用内部函数来封装唯一键的详细信息。

类接口(interface)的一些建议:

// use typedefs to make changes easier
typedef string KEY_TYPE;
typedef map<KEY_TYPE, Person> PERSON_POOL;
typedef vector<Person> PERSONS;

class PersonPool
{
public:
void add_person(const Person& p);
void update_person(const Person& p);
Person get_person(string name, string address);
void remove_person(string name, string address);
bool person_exists(string name, string address);

// find zero or more persons
PERSONS get_persons_by_name(string name);
PERSONS get_persons_by_address(string address);
PERSONS get_persons_by_number(string number);

private:
KEY_TYPE get_key(string name, string address);
KEY_TYPE get_key(const Person &p);
PERSON_POOL m_persons;
};

示例实现:

void Person::add_person(const Person& p)
{
m_persons.insert(get_key(p), p);
}

Person Person::get_person(const Person& p)
{
PERSON_POOL::iterator i = find(m_persons.begin(), m_persons.end(), get_key(p));
if (i != m_persons.end())
return i->second;
throw "person not found";
}

无论如何,祝你的项目好运。

关于c++ - 实现存储类来存储某个类的多个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19515480/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com