(是的,这是一个家庭作业)
我正在尝试创建一个简单的数据库,其中一个人通过名称+地址组合或唯一的帐号识别。我需要能够在提供acc编号或名称+ addr时快速添加/删除/访问有关某人的信息。
我创建了一个没有帐户的版本(使用重载运算符<用于使用lower_bound在数据库中搜索),现在我正在尝试添加帐户功能。
这就是我所拥有的:
struct SPerson
{
string s_name, s_addr;
int s_income, s_expense;
SAccount * s_accountPtr;
SPerson ( const string &, const string & ); // constructor
};
struct SAccount
{
string s_account;
SPerson * s_personPtr;
SPerson ( const string & ); // constructor
};
这个想法是有一个帐户向量和一个人的向量,并保持它们与指针链接。在我遇到这些问题之前看起来很简单:
我能以某种方式完成这项工作吗?
bool CDatabase::Birth ( const string & name, const string & addr, const string & account )
{
SPerson personToAdd = SPerson ( name, addr );
SAccount accountToAdd = SAccount ( account );
SPiter = lower_bound ( SPeople.begin ( ), SPeople.end ( ), personToAdd );
SAiter = lower_bound ( SAccounts.begin ( ), SAccounts.end ( ), AccountToAdd );
if ( ( SPiter -> s_name == name &&
SPiter -> s_addr == addr ) ||
SAiter -> s_account == account ) return false;
personToAdd.s_accountPtr = & accountToAdd; // this is proabably very wrong
accoutToAdd.s_personPtr = & personToAdd;
SPeople.insert ( SPiter, personToAdd ); // does this mess up the pointers?
SAccounts.insert ( SAiter, accountToAdd );
return true;
}
//我很抱歉代码格式化会杀了我,要尽快修复
答案 0 :(得分:3)
If I create an object and insert it into a vector, does a copy of that object get created and inserted? Or is it the original object?
如果您使用push_back
或insert
,则会制作副本。如果您不想使用emplace_back
副本。在向量的末尾以外的任何位置插入元素是低效的,因为它会在插入点之后移动所有元素或者更糟糕地移动所有元素。
What happens with the addresses of objects in a vector when I insert something into it?
它们可能会也可能不会发生变化,具体取决于矢量的大小和插入位置。所以有向量元素的原始指针可能是一个坏主意。一旦你在中间插入一些东西或者矢量超出其容量,所有指针都可能指向无意义。
Can I even make this work somehow?
是的,只需使用句柄而不是原始指针。如果您被允许使用不同的数据结构,例如std::map
std::unordered_set
来检索帐户/人,而不必通过向量并比较句柄。
答案 1 :(得分:0)
在我看来,您尝试在relationship
和SAccount
更具体地SPerson
关系之间完成某种one-to-one
因此,我建议您模拟数据库系统的实际行为。
你可以拥有SAccount
这样的课程:
struct SAccount
{
string s_account;
int person_id; // Since id is unique.
SAccount ( const int ); // constructor
};
这样每个account
都会拥有一个人的id
。
修改:更新
struct SPerson
{
static id=0;
string s_name, s_addr;
int s_income, s_expense;
int pid, account_id;
SPerson ( const string &, const string & , int account_id, person_id=++Sperson::id); // constructor
};
struct SAccount
{
static id=0;
string s_account;
int aid, person_id;
SPerson ( const string & , int person_id, int account_id=++SAccount::id); // constructor
};
使用静态属性,您关心自动ID生成。
答案 2 :(得分:0)
一个简单的解决方案是在向量中保留指向人员和帐户的指针。即使这在实现数据库时意味着更加谨慎,它也可以极大地简化从向量中插入和删除对象的设计和性能。
现在有一千人会争辩说,一个人必须至少使用引用计数智能指针,在这种特殊情况下我仍会反对他们: - )。
答案 3 :(得分:0)
首先,我要感谢你的回答(再一次,我通过询问原始问题发现了大约一百万个新事物)但我决定不使用任何解决方案 - 我去了为此:
我保持SPeople矢量排序,每次我在那里插入一个新人,我也在同一个索引下向SAccounts插入一个新帐户(因此,这个没有排序)。这样,我可以在O(log n)中给出人员信息时访问帐户。另一方面,考虑到帐户信息,搜索是线性的,但我被告知线性搜索仍然足够快。
我在实施上述系统时遇到一些问题,但这不是这个问题的主题,我将发布另一个问题来讨论这个问题。 :)