遍历对象列表C ++

时间:2018-09-06 04:28:50

标签: c++ list class object listiterator

基本上,我正在为一个类项目创建一个基本的shell程序。我一直在遍历目录中的文件/文件夹。

我的错误出在函数DisplayDirectoryContents()

class Directory 
{
private:
map<string, pair<list<Folder>, list<File> > > directoryContents;
string directoryPath;

public:
list<Folder> getFolders() {return directoryContents[directoryPath].first;}
list<File> getFiles() {return directoryContents[directoryPath].second;}
string getDirectoryPath() {return directoryPath;}

Directory() 
{
    directoryPath = "root/"; 
    File *file = new File("Test");
    directoryContents[directoryPath].second.push_back(*file);
}
void DisplayDirectoryContents()
{
    // Get files and folders from directory
    list<File> files = this->getFiles();

    for(int i = 0; i < files.size(); i++)
    {
        cout << files->getFileName(); << Error here
    }

}
};

我尝试通过几种不同的方式设置此功能,但似乎无法获得正确的代码来使其正常工作。

我认为这会起作用,但是每次尝试弄乱DisplayDirectoryContents()函数时,都会抛出错误。有没有人有任何技巧可以帮助我解决此问题?谢谢

class File
{
string fileName;
string fileTime;
public:
string getFileTime(){return fileTime;}
string getFileName(){return fileName;}

void setFileTime(){time_t now = time(NULL);
                fileTime = ctime(&now);} 
void setFileName(string newFileName){fileName = newFileName;}
File(){}
File(string fName)
{
    fileName = fName;
    time_t now = time(NULL);
    fileTime = ctime(&now);
}
void MakeFile(string fName);
void RemoveFile(string fName); 
};

2 个答案:

答案 0 :(得分:1)

如果您能够使用C ++ 11或更高版本,则可以使用范围{{1}}循环遍历列表的内容。

{{1}}

答案 1 :(得分:1)

扩展到R Sahuanswer

您无法使用原始循环进行迭代的原因是因为std::list没有提供索引运算符(您需要使用std::vector来代替)。

基于范围的for循环的替代方法(不过,除非您有特殊原因,我还是更喜欢这样做)–如果没有C ++ 11可用,该方法是使用迭代器:

for(std::list<File>::iterator i = files.begin(); i != files.end; ++i)
{
    std::cout << i->getFileName();
}

使用C ++ 11,您可以拥有for(auto i = files.begin(); ...

即使在C ++ 11中使用迭代器循环的用例也可以将项目与其后续项目进行比较:

// check for empty list first, as std::prev would fail on!)
for(auto i = files.begin(); i != std::prev(files.end()); ++i)
{
    if(someCondition(*i, *std::next(i))
    {
        // do something else
    }
}

已经有std::remove_if了,您应该更喜欢它(与lambda一起使用;但是不要忘了之后再应用erase,请参阅erase-remove-idiom!),因此仅出于说明目的;从更简单的方法开始:

for(auto i = files.begin(); i != files.end(); ) // no ++i (!)
{
    if(condition)
    {
        i = files.erase(i);
        // fine for std::list; with std::vector, if removing more
        // than one single element, we'd move or even copy subsequent
        // elements multiple times, which is quite inefficient
    }
}

改进的变体(std::remove_if也是如此)

auto pos = files.begin();
for(auto i = files.begin(); i != files.end(); ++i)
{
    if(!condition)
    // ^ (!)
    {
        *pos++ = std::move(*i);
    }
}
// here, std::remove_if already stops, but returns pos...
files.erase(pos, files.end());

移动或副本分配运算符可能无法正确处理自我分配,这可能是一个最小的问题,这将由if(!condition && i != pos)涵盖。