如何存储对象供以后使用并使其可搜索

nat*_*tli 9 c++ struct pointers class object

目前我每次使用一个向量来存储指向对象的指针,但这感觉有点傻.可能有更好的方法,但我还没找到.

What I'm doing:                      Example usage:

原型

问题:

  1. 如果我想要检索某个日期,我必须遍历向量中的所有项目,以查看RecPaymentsStack.stackDate是否与用户请求的日期匹配.
  2. RecPaymentStack目前实际上完全没用,因为我应该做的是,在添加新项目时,检查是否已经为新项目的Date属性创建了"RecPaymentStack.stackDate",如果是,则添加新指针将"RecPayments"转换为"RecPaymentStack"对象内的指针数组.但是怎么样?

我可能不必要地复杂的事情(这是我做了很多),所以如何像这样的explenation 应该做将是非常好的.

详细信息:(如果我太模糊了)

以下示例应该类似于可以保存某些项目(RecPayments)的日历,并且这些项目按日期分组(RecPaymentsStack).

struct RecPayments
{
    std::string name;
    Date* date;
    float cost;
};

struct RecPaymentsStack
{
    Date* stackDate; //This stack's date
    RecPayments * thePaymentItem; //Hold pointer to the actual item
};
Run Code Online (Sandbox Code Playgroud)

这就是我目前正在存储它们的方式

std::vector<RecPaymentsStack*> RecPaymentsVector; //This vector will hold pointers to all the Recurring Payments

void addRecurring(std::string theDate,std::string theName,float theCost)
{
    //New recurring payment
    RecPayments * newPaymentItem = new RecPayments;
    //Set recurring payment properties
    newPaymentItem->name = theName;
    newPaymentItem->date = new Date(stringToChar(theDate));
    newPaymentItem->cost = theCost;

    //Add recurring payment to stack
    RecPaymentsStack * addToStack = new RecPaymentsStack;
    addToStack->stackDate = new Date(stringToChar(theDate));
    addToStack->thePaymentItem = newPaymentItem;

    //Add pointer to RecPaymentsStack to vector
    RecPaymentsVector.push_back(addToStack);
}
Run Code Online (Sandbox Code Playgroud)

因此,为了检索给定日期的项目,我目前正在遍历向量中的所有指针,以查看"stackDate"属性是否与请求的日期匹配,如果是,我使用"thePaymentItem"属性来显示实际项目.

void getItemsNow(Date requestedDate)
{
    std::cout << "Showing Dates for " << requestedDate << std::endl;
    unsigned int i;
    for(i=0;i<RecPaymentsVector.size();i++) //Go over all items in vector
    {
        Date dateInVector(*RecPaymentsVector[i]->stackDate); //Get the date from the vector
        if(dateInVector == requestedDate) //See if Date matches what the user requested
        {
            //Date matched, show user the item properties.
            std::cout << "Date: " << dateInVector <<
                " has name: " << RecPaymentsVector[i]->thePaymentItem->name <<
                " and price " << RecPaymentsVector[i]->thePaymentItem->cost <<
                std::endl;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

3个问题:

  1. 如果我只需要几个指针,那么遍历向量中的所有项目效率非常低
  2. RecPaymentStack目前实际上完全没用,因为我应该做的是,在添加新项目时,检查是否已经为新项目的Date属性创建了"RecPaymentStack.stackDate",如果是,则添加新指针将"RecPayments"转换为"RecPaymentStack"对象内的指针数组.但是怎么样?
  3. 所有这一切都让人觉得非常愚蠢......这可能是一种更容易/更专业的方式来做到这一点,但我找不到什么,可能是因为我还在想像一个PHPer.

所以这里的一般想法是我最终做的事情(愚蠢的例子)

for each RecPaymentsStack->stackDate //For each unique Date, show it's children items.
{
    cout << "The Date is " CurrentRecPaymentsStack->stackDate and it holds the following items:
    for each CurrentRecPaymentsStack->thePaymentItem //This would now be an array of pointers
    {
        cout << "item name " CurrentRecPaymentsStack->thePaymentItem->name << " with cost " << CurrentRecPaymentsStack->thePaymentItem->cost << endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将基本上覆盖所有独特的"RecPaymentsStack"对象(由其"Date"属性确定的唯一对象),然后对于每个Date,它将从RecPayments结构中显示它的"子".

必须有一些方法来搜索特定的日期,而不必浏览所有可用的日期.

Nik*_* B. 2

您不应使用向量来管理项目,而应将RecPaymentsStack实例替换为std::multimap. 键类型是您的Date结构,值类型是RecPayments(我将其更改为单数形式RecPayment)。小例子(未经测试):

typedef std::multimap<Date, RecPayment> RecPaymentsByDateMap;
typedef std::pair<RecPaymentsByDateMap::iterator, 
                  RecPaymentsByDateMap::iterator>
                                        RecPaymentsByDateMapIters;

RecPaymentsByDateMap payments_by_date;

RecPaymentsByDateMapIters findByDate(Date date) {
  return payments_by_date.equal_range(date);
}

...

// find all payments with the given date
RecPaymentsByDateMapIters iters = findByDate(...);
for (RecPaymentsByDateMap::iterator it = iters.first;
     it != iters.second;
     ++it)
{
  std::cout << "Payment " << it->second.name << std::endl;
}
Run Code Online (Sandbox Code Playgroud)