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

时间:2011-12-04 22:19:20

标签: c++ class object pointers struct

目前我正在使用向量存储指向对象的指针,但是这感觉有点傻。可能有更好的方法,但我还没找到。

What I'm doing:                      Example usage:

prototype

问题

  1. 如果我想要检索某个日期,我必须查看向量中的所有项目,以查看RecPaymentsStack.stackDate是否与用户请求的日期相匹配。
  2. RecPaymentStack目前实际上完全没用,因为我应该正在做什么,当添加新项目时,检查是否已经为新项目制作了“RecPaymentStack.stackDate” Date属性,如果是,则将“RecPayments”的新指针添加到“RecPaymentStack”对象内的数组指针。但是怎么样?
  3. 我可能不必要地使事情变得复杂(我做了很多事情),所以对这样的事情应该这样做的表达非常好。

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

    以下示例应该类似于可以保存某些项目的日历(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
    };
    

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

    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);
    }
    

    因此,要检索给定日期的项目,我目前正在查看向量中的所有指针,以查看“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;
            }
        }
    }
    

    3个问题:

    1. 如果我这样做的话,在向量中的所有项目都是非常低效的 需要几个指针
    2. RecPaymentStack目前实际上完全没用,因为我应该正在做什么,当添加新项目时,检查是否已经为新项目制作了“RecPaymentStack.stackDate” Date属性,如果是,则将“RecPayments”的新指针添加到“RecPaymentStack”对象内的数组指针。但是怎么样?
    3. 所有这一切都让人觉得非常愚蠢......这可能是一种更容易/更专业的方式,但我找不到什么,可能是因为我还在想像一个PHPer。
    4. 所以这里的一般想法是我最终做的事情(愚蠢的例子)

      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;
          }
      }
      

      这基本上会覆盖所有独特的“RecPaymentsStack”对象(由它的“Date”属性决定),对于每个Date,它会从RecPayments结构中显示它的“children”。

      必须有一些方法可以搜索特定日期,而无需查看所有可用日期。

2 个答案:

答案 0 :(得分:2)

您应该使用std::multimap替换RecPaymentsStack实例,而不是使用向量来管理您的商品。密钥类型是您的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;
}

答案 1 :(得分:1)

我可能会这样设计 - 这只是一个简单的想法,细节应根据您​​的要求进行调整:

#include <deque>
#include <map>
#include <string>

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

struct RecPaymentsStack
{
    Date stackDate;
    std::deque<RecPayment> thePaymentItem;

    bool operator<(RecPaymentsStack const & rhs) const
    {
      return stackDate < rhs.stackDate;
    }

    explicit RecPaymentsStack(Date const & d) : stackDate(d) { }
};

typedef std::multimap<RecPaymentsStack> PaymentsCollection;

现在您可以插入元素:

PaymentsCollection payments;

{
  auto it = payments.emplace(Date("..."));
  it->thePaymentItem.emplace_back(Payment{name1, date1, cost1});
  it->thePaymentItem.emplace_back(Payment{name2, date2, cost2});
  it->thePaymentItem.emplace_back(Payment{name3, date3, cost3});
}