我们有一个存储类Person
,具有以下定义:
class Person
{
public:
string m_name;
string m_address;
string m_phone_number;
};
我们希望有一个存储类
PersonPool
,它存储所有Person的实例。类(class)要求:
我们建议以下类(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
};
使用范例
说我有这段代码:
问题
示例中的第6行修改了
Person
的地址。当我想基于新地址(“y”)获取
Person
时,PersonPool
将无法返回此Person
。它不“知道”地址已被修改,仍然将旧地址“x”作为该Person实例的密钥。有关
PersonPool
增强的建议:问题:
Person
的用户修改(即使m_name可能被修改)怎么办PersonPool
添加函数:void update_person(字符串old_address,字符串new_address)
问题:
PersonPool
中的对Person的任何修改都必须使用PersonPool
提供的新功能来完成问题:
Person
中复制PersonPool
接口(interface)。我们当然不想这样做。 题:
您能想到一个更好的
PersonPool
实现。是否可以调整我的建议并摆脱此问题。谢谢您的宝贵时间!
最佳答案
我真的不能说这是否是学术 Activity 。无论如何,很难确定哪种特定的存储实现将为您带来最佳性能。这将取决于许多因素,包括(但不限于):
我将采用的方法是设计类接口(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";
}
无论如何,祝您的项目好运。