簡體   English   中英

迭代對象列表 C++

[英]Iterating over a list of objects c++

基本上我正在為一個類項目創建一個基本的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); 
};

擴展R Sahu回答

您不能使用原始循環進行迭代的原因是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 for 並且您應該更喜歡它(與 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)覆蓋。

如果您能夠使用 C++11 或更高版本,則可以使用范圍for循環來迭代列表的內容。

void DisplayDirectoryContents()
{
    // Get files and folders from directory
    list<File> files = this->getFiles();

    // Iterate over each item in the list.
    // Use a reference to avoid copying of the items.
    for ( File& file : files )
    {
        cout << file.getFileName();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM