有点困惑的范围,以及如何为目录树创建嵌套的结构

问题描述:

我试图显示从平面文件中读取的未知数量的嵌套文件夹的目录树UI。我的想法是使用结构可能指向孩子和家长,像这样:有点困惑的范围,以及如何为目录树创建嵌套的结构

struct audioSelectTreeItem { 
    FString folderName; 
    FString folderPath; 
    struct audioSelectTreeItem* folderParentItem; 
    TArray<struct audioSelectTreeItem*> childFolderItems; 
}; 

当我读到保存目录的文件我保存childFolderItems所有子文件夹和folderParentItem父。这样在我的界面,如果有人想上去一个文件夹,我看着folderParentItem,然后列出它的子文件夹与childFolderItems。

我遇到的问题是如何保存这个。我做了一个循环遍历文件夹和子项的函数,可以创建所有这些结构并保存它们。然而,我认为的问题是,如果我在一个循环中创建一个结构,然后在前面的结构(子文件夹)中保存一个指向它的指针,我无法从程序中的其他任何地方访问它。

有没有一种方法可以完成创建这些更加永久性的功能,以及我在完成后如何去清理?

编辑:写道,如果我正在阅读实时目录。是一个带有目录信息的文本文件,我需要将其放入树形界面。

更新: 这里的环做什么一个小例子:

void AMyPlayerController::showAudioPicks() { 
for (int counter = startCount; counter < fileStringArray.Num(); counter++) { //startcount 3 

     audioSelectTreeItem newTreeItem; 
     newTreeItem.folderPath = fileStringArray[counter]; 
     mainListTree.childFolderItems.Add(&newTreeItem); 

...

所以我的问题在于创造这些新audioSelectTreeItem的添加嵌套结构,但让他们访问其他地方在节目中。

+0

调用用户定义的函数'GetDirectoryContent(audioSelectTreeItem p_asti)'来显示'self-repeataion loop'中的子文件夹和文件。您只需要选择要保存目录数据的文件夹和向量的广告路径。 –

+0

@ A.Godnov对不起,我写如果我正在从一个实时目录阅读。我实际上是这么做的,并且正在从“保存的目录”保存的文件中读取 – Shawn

+0

您正在阅读的文件的格式是什么? –

什么,你在这里做的是创建一个指向它的作用范围是for循环和摧毁在每个循环堆栈变量:

audioSelectTreeItem newTreeItem; 
newTreeItem.folderPath = fileStringArray[counter]; 
mainListTree.childFolderItems.Add(&newTreeItem); 

如果你想创建的一个对象(或结构)堆而不是堆栈,你必须使用new

audioSelectTreeItem *newTreeItem = new audioSelectTreeItem; 
newTreeItem->folderPath = fileStringArray[counter]; 
mainListTree.childFolderItems.Add(newTreeItem); 

但是,如果你这样做,你必须确保该对象被释放与delete。通常,这是在audioSelectTreeItem类(或结构)的析构函数来完成:

class audioSelectTreeItem { 
public: 
    ~audioSelectTreeItem() 
    { 
     for (int i = 0; i < childFolderItems.Num(); i++) 
      delete childFolderItems[i]; 
    } 

    FString folderName; 
    FString folderPath; 
    class audioSelectTreeItem* folderParentItem; 
    TArray<class audioSelectTreeItem*> childFolderItems; 
}; 

父是其子的主人,所以在删除folderParentItem没有意义的。一旦你删除了根,它的析构函数就会删除他所有的子项等等。

在当前的C++中,像这样的树有更安全的解决方案。例如,你可以使用托管指针而不是普通指针。这就形成了一个位,因为引用计数的开销,但你从来没有给自己释放堆:

#include <memory> 

class audioSelectTreeItem 
{ 
public: 
    FString folderName; 
    FString folderPath; 
    std::weak_ptr<audioSelectTreeItem> folderParentItem; 
    TArray<std::shared_ptr<audioSelectTreeItem>> childFolderItems; 
}; 

不要使用一个shared_ptr的folderParentItem参考。这将导致循环依赖(父引用子引用父引用,因此它们都不能被删除)

而个人观点:类型名称应该以大写字母开头。

+0

谢谢!我认为这回答我的问题 – Shawn

+0

我会建议使用一个单一的列表(标准::矢量)与结构像'struct { \t FString folderName; \t FString folderPath; \t size_t parentIndex; };'。序列化和反序列化很简单,管理起来也很简单。 –