保持两个按指针链接的排序向量

时间:2014-03-20 21:02:42

标签: c++ pointers vector

(是的,这是一个家庭作业)

我正在尝试创建一个简单的数据库,其中一个人通过名称+地址组合或唯一的帐号识别。我需要能够在提供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;
    

    }

//我很抱歉代码格式化会杀了我,要尽快修复

4 个答案:

答案 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_backinsert,则会制作副本。如果您不想使用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)

在我看来,您尝试在relationshipSAccount更具体地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)中给出人员信息时访问帐户。另一方面,考虑到帐户信息,搜索是线性的,但我被告知线性搜索仍然足够快。

我在实施上述系统时遇到一些问题,但这不是这个问题的主题,我将发布另一个问题来讨论这个问题。 :)