遍历一个对象向量并找到一个与从文本文件中提取的变量相匹配的变量

Iterate through a vector of objects and find a variable that matches one pulled from a text file

所以我有一个对象向量

vector<Module*> moduleVector;         

我需要遍历它并将对象的属性与我从文本文件中提取的另一个属性进行比较

我正在使用 ifstreamgetLine() 来存储需要与对象属性进行比较的元素(fileD 是打开的文件,markModId是字符串变量)

getline(fileD, markModId, ' ');

但我不确定如何在迭代器中引用对象的属性。所以我的问题是,

如何使用迭代器比较文件和对象的属性?

参考这里是我的对象构造函数(id是我要比较的属性)

Module::Module(string id, string title, string lecturer, int 
courseworkWeight)
{
   code = id;
   name = title;
   lect = lecturer;
   cwWeight = courseworkWeight;
   exMark = 0; //ex mark initialised as 0
   /*
   Map to store coursework marks
   */
   map<string, float> CWmarks;
   //cwMarks.clear(); //cw marks map cleared
   //create a map that stores
}

exMark是对象需要添加的属性。 Module 构造函数中的所有属性都是 private.

简单地取消对迭代器的引用以访问其 Module* 指针,然后您可以使用 operator-> 访问该对象,但是您想要,例如:

for (std::vector<Module*>::iterator iter = moduleVector.begin(), end = moduleVector.end(); iter != end; ++iter)
{
    Module *m = *iter;
    if (m->code == markModId)
        m->exMark = ...;
}

或者,如果您使用的是 C++11 或更高版本,让编译器为您处理迭代器:

for (Module *m : moduleVector)
{
    if (m->code == markModId)
        m->exMark = ...;
}

或者,使用具有标准迭代算法之一的 lambda,例如:

std::for_each(moduleVector.begin(), moduleVector.end(),
    [&](Module *m)
    {
        if (m->code == markModId)
            m->exMark = ...;
    }
);

如果您只对更新 1 个模块感兴趣,则在找到所需模块后打破循环:

for (std::vector<Module*>::iterator iter = moduleVector.begin(), end = moduleVector.end(); iter != end; ++iter)
{
    Module *m = *iter;
    if (m->code == markModId)
    {
        m->exMark = ...;
        break; // <-- add this
    }
}

for (Module *m : moduleVector)
{
    if (m->code == markModId)
    {
        m->exMark = ...;
        break; // <-- add this
    }
}

auto iter = std::find_if(moduleVector.begin(), moduleVector.end(),
    [&](Module *m) { return (m->code == markModId); });
if (iter != moduleVector.end())
{
    Module *m = *iter;
    m->exMark = ...;
}

How do I compare the attribute from the file to the object using an iterator?

简答:假设你有一个迭代器std::vector<Module*>::iterator iter,你可以访问Moduleclass的public成员,比如:

(*iter)->/*public member*/;

长答案:首先,您需要一个 getter 用于私有成员 id 和一个 setter 用于 exMark,通过它你可以获得每个 Moduleid 并与文件中的 id 进行比较,然后将其 exMark 设置为某个值。

std::string getId()const { return code; }
void setExMark(const double newMark) { exMark = newMark; }

如果要更改 Module 的第一个真实实例,可以使用 std::find_if 查找 Module:

std::string idFromFile = "two";
auto Condition = [&idFromFile](Module* element){ return element->getId() == idFromFile; };
auto iter = std::find_if(moduleVector.begin(), moduleVector.end(), Condition);

if(iter != moduleVector.end())
     (*iter)->setExMark(10.0);  // see this
   // ^^^^^^^^^

See a sample code here

对于多个实例,您可以执行以下操作:

for(auto iter = moduleVector.begin(); iter != moduleVector.end(); ++iter)
      if ( (*iter)->getId() == idFromFile)
         (*iter)->setExMark(10.0);

注意:在现代 C++ 中,您可以使用 smart pointers,而不是原始指针,它会在超出范围时自动删除对象。