2017-10-17 17 views
0

플랫 파일에서 읽지 않은 중첩 된 폴더의 알 수없는 양에 대한 디렉토리 트리 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-repeatation loop'에 표시합니다. dir 데이터를 저장하려는 선택한 폴더와 벡터의 Adspath 만 필요합니다. –

+0

@ A.Godnov 죄송합니다. 라이브 디렉토리에서 읽는 것처럼 씁니다. 실제로 이전에 그렇게했으며 "저장된 디렉토리"의 저장된 파일을 읽습니다. – Shawn

+0

읽고있는 파일의 형식은 무엇입니까? –

답변

1

당신이 모든 루프 for 루프로 범위 및 파괴 스택 변수에 대한 포인터를 만드는 여기서 뭐하는 : 당신의 오브젝트 (또는 구조)를 만들려면

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

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

을하지만 그렇게 할 경우, 당신은 객체가 delete으로 해제되어 있는지 확인해야한다 : 대신 스택의 힙, 당신은 new을 사용해야합니다. 일반적으로이는 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; 
}; 

는 folderParentItem의 참조를 위해 shared_ptr을 사용하지 마십시오. 이것은 순환 종속성으로 이어질 것입니다 (부모 참조 자식 및 자식 참조 부모, 그래서 그들 중 누구도 삭제할 수 있습니다)

그리고 개인 의견 : 형식 이름은 대문자로 시작해야합니다.

+0

감사! 내 질문에 대한 답변을 생각합니다 – Shawn

+0

'struct { \t FString folderName과 같은 구조로 단일 목록 (std :: vector)을 사용하는 것이 좋습니다. \t FString folderPath; \t size_t parentIndex; }; 직렬화 및 비 직렬화 및 관리가 간단합니다. –