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

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

如果问题有点模糊,让我们举个例子class 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 及更高版本的每个循环都有,那段代码就不是很 "pretty" 了。如何使用 "for-each" 语法删除动态分配的指针数组?以下显然在语法上不正确:

for(Paper* p: myFolder)
    delete p;

甚至

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

附加信息: myFolder 不是数组的数组。它是一个指针数组。为什么?因为objective就是利用了多态性。 Paper 可能被子classed,因此myFolder 是一个指针数组而不是对象数组。

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

您可以使用 std::for_each 和一些指针算法。

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

然而,本着使用现代 C++ 的精神,我根本不鼓励使用手动内存操作,而是使用 RAII

的东西
std::vector<std::vector<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)

因为你想要多态性,你需要持有指向你的对象的指针。 您当前使用指向动态分配数组的指针

Paper** myFolder;

无需手动控制数组的分配,可以轻松使用

std::vector<Paper*> myFolder;

销毁文件夹时,漂亮:

for(auto paper : myFolder) 
    delete paper;