如何使用for-each循环来美化析构函数

How can I use a for-each loop to beautify a destructor?

本文关键字:析构函数 循环 何使用 for-each      更新时间:2023-10-16

如果问题有点模糊,让我们使用示例类Paper

假设我有一个动态分配的指针数组:

Paper** myFolder;

之后,在某个地方,它被n个指针填满了:

myFolder = new Paper* [n];
//trimmed - make each pointer in myFolder point to something

当我们完成myFolder时,我们需要在删除Paper**之前删除每个Paper:

for(int i = 0; i < n; i++)
    delete myfolder[i];

我的问题:这段代码现在不是很"漂亮",因为c++ 11和更高版本的每个循环都有。我如何删除一个动态分配的指针数组与"for-each"语法工作?下面显然是语法错误的:

for(Paper* p: myFolder)
    delete p;

或者

for each (Paper* p in myFolder)
    delete p;

附加信息: myFolder不是数组的数组。它是一个指针数组。为什么?因为我们的目标是利用多态性。Paper可以被子类化,因此myFolder是指针数组而不是对象数组。

当然,std::vector是比使用原始指针更好的方法。这个问题是理论性的,只涉及新的c++语法。我不是在寻找关于如何重做这段代码的建议

您可以使用std::for_each与一些指针运算。

std::for_each(myFolder, myFolder + n, [](Paper* p){ delete[] p; })

然而,在使用现代c++的精神中,我完全不鼓励使用手动内存操作,而是使用RAII

std::vector<std::vector<Paper>>

由于需要多态性,因此需要保存指向对象的指针。当前使用的指针指向动态分配的数组

纸* * myFolder;

不需要手动控制数组的分配,您可以轻松地使用

std::vector<Paper*> myFolder;

销毁文件夹时,优美地:

for(auto paper : myFolder) 
    delete paper;

应该避免使用原始指针。

下面是一个使用std::vector来解决问题的例子。

#include <vector>
class Paper {
};
class Folder {
    // A folder contains a vector of papers.
    std::vector<Paper> m_papers;
public:
    // Method to add a paper to the folder. Use Move semantics for performance.
    void AddPaper(Paper && aPaper) {
        m_papers.push_back(std::move(aPaper));
    }
    // A read-only getter.
    const std::vector<Paper> & Papers() const { return m_papers; }
};
int main()
{
    std::vector<Folder> folders;  // All your folders.
    Folder aFolder;   // Create a folder.
    aFolder.AddPaper(Paper());  // Add paper to the folder.
    folders.push_back(aFolder);  // Add a folder.
    for (const auto & f : folders) {
        for (const auto & p : f.Papers()) {
            // Read each paper here.
        }
    }
}

当使用std::vector时,可以使用范围for循环访问每个元素:

for (const auto & f : folders)