1

은 다음 클래스를 고려적절한 개체 폐기

public ref class Workspace 
{ 
protected: 
    Form^     WorkspaceUI; 
    SplitContainer^  WorkspaceSplitter; 
    AvalonEditTextEditor^ TextEditor; 
    ScriptOffsetViewer^ OffsetViewer; 
    SimpleTextViewer^  PreprocessedTextViewer; 

    ListView^    MessageList; 
    ListView^    FindList; 
    ListView^    BookmarkList; 
    ListView^    VariableIndexList; 
    TextBox^    VariableIndexEditBox; 
    Label^    SpoilerText; 

    ToolStrip^   WorkspaceMainToolBar; 
    ToolStripButton^  ToolBarNewScript; 
    ToolStripButton^  ToolBarOpenScript; 
    ToolStripButton^  ToolBarPreviousScript; 
    ToolStripButton^  ToolBarNextScript; 
    ToolStripSplitButton^ ToolBarSaveScript; 
    ToolStripDropDown^ ToolBarSaveScriptDropDown; 
    ToolStripButton^  ToolBarSaveScriptNoCompile; 
    ToolStripButton^  ToolBarSaveScriptAndPlugin; 
    ToolStripButton^  ToolBarRecompileScripts; 
    ToolStripButton^  ToolBarCompileDependencies; 
    ToolStripButton^  ToolBarDeleteScript; 
    ToolStripButton^  ToolBarNavigationBack; 
    ToolStripButton^  ToolBarNavigationForward; 
    ToolStripButton^  ToolBarSaveAll; 
    ToolStripButton^  ToolBarOptions; 

    ArbitraryCustomClass^ CustomClassInstance; 

public: 
    Workspace() 
    { 
     WorkspaceUI = gcnew Form(); 
     WorkspaceSplitter = gcnew SplitContainer(); 
     // ... 
     Form->Controls->Add(WorkspaceSplitter); 
     // ... 

     WorkspaceUI->Show(); 
    } 

    ~Workspace 
    { 
     // dispose stuff here 
    } 
}; 

메모리 모두가 GC 회수되도록 위의 클래스의 인스턴스를 처리 할 수있는 가장 효율적이고 우아한 방법이 될 것입니다 무엇 다음 컬렉션 중에? 각 회원에게 명시 적으로 전화를 걸거나 nullptr으로 재설정해야합니까?

답변

5

NB. 아무 것도 할 필요가 없을 수도 있습니다. 객체를 가리키는 참조가 더 이상 존재하지 않으면 객체 메모리가 GC에 의해 교정됩니다.

개체가 IDisposable을 구현할 때 명시 적으로 만 요구하면됩니다. C++/CLI에서 이것은 소멸자에 매핑됩니다.

할당하려는 객체를 모두 삭제해야하는 경우 나머지 답변은 무시해도됩니다. 그러나 그들이한다고 가정하면 ...

각 필드에서 ^을 제거하면 자동으로 교정됩니다.

Workspace이 생성 될 때 자동으로 기본값으로 생성되므로 손으로 작성한 생성자에 많은 gcnew 내용을 저장할 수 있습니다.

다음
Form WorkspaceUI; 

말 할 필요가 없습니다 : 당신이 말하는 경우이다

컴파일러는 이미 당신이 것을 생성 한

WorkspaceUI = gcnew Form(); 
- 상상이 시작 부분에 삽입되는 귀하의 생성자의.

아니요 삭제하거나 삭제해야 할 항목이 없습니다.

Form.Controls->Add(WorkspaceSplitter); 

업데이트 : : C++/CLI에서

가, 심판 핸들

마지막으로, 당신은 당신이 이런 식으로 선언 객체의 멤버에 액세스하는 대신 ->.를 사용할 필요가 클래스는 ^으로 선언되며 이는 기본 클래스에 대한 포인터가 *으로 선언되는 방식과 유사합니다.

또한 그에 상응하여 개체에 대한 핸들을 가져 오는 방법이 필요합니다. 네이티브 개체에 대한 포인터를 얻으려면 &이라는 접두사가 붙습니다. ref 객체에 대한 핸들을 얻으려면 %이라는 접두사를 붙입니다. 예를 들어 : 그것에

  • 당신은 실수로 들고 참조 (또는 무언가가 할당) :

    ref class Fred { }; 
    
    // function that accepts a handle 
    void ping(Fred ^h) { } 
    
    // Elsewhere... declare object of type Fred 
    Fred f; 
    
    // Get handle to pass to function 
    ping(%f); 
    

    반복적으로 작성 및 클래스의 객체를 삭제하는 경우이 두 가지 가능성이 메모리 부족에 이르게 .이 질문에 대한 내 대답을 참조하십시오 : Memory Leaks in C# WPF (C# 또는 WPF와 관련이있는 것은 없습니다. 대화 형으로 디버거를 사용하는 것입니다.)

  • 하나 이상의 개체에 대해 Dispose을 호출해야합니다. 클래스 내부에 할당하십시오.

거기 내장되어 C++/CLI에서 지원 자동 Dispose를 호출, 후자의 경우 - 그것은 소멸자와 C++ 심판 클래스 인 것처럼 C++/CLI는 일회용 개체를 처리합니다.

그래서 핸들을 삭제하면 핸들이 가리키는 객체에 Dispose이 호출됩니다.

회원이 단순히 개체를 가지고 있다면 (명시 적으로 상기 한 것처럼) 명시 적으로 삭제할 필요조차 없습니다. 외부 포함 클래스가 소멸되면 (즉, 무언가가 Dispose 메소드를 호출하면),이를 필요로하는 모든 구성원 객체에서 자동으로 Dispose이 호출됩니다.

+0

그런 경우 개체를 처리해야하는 함수에 개체를 전달하는 방법은 무엇입니까? 마찬가지로 : Label SomeText; Form.Controls-> Add (SomeText); // 컴파일러 오류가 발생합니다 – shadeMe

+0

또한 위 클래스의 생성 및 제거가 계속되면 System.OutOfMemoryException이 발생합니다. - GC가 객체의 메모리를 회수하지 않는 것 같습니다. 이것은 과거의 파멸에 대한 강한 언급을 가지고 있다고 믿게합니다. 내 코드에서는 모든 클래스의 인스턴스가 할당되어 목록에 직접 추가됩니다. 파기되면 인스턴스가 인스턴스에서 제거됩니다. 이것이 각 인스턴스가 루트에서 얻는 유일한 참조입니다. 그러나 클래스의 여러 멤버가 만든 여러 개의 내부 참조가 있습니다. – shadeMe

+0

@shadeMe : 모든 소유 객체의 폐기를 시작하려면'Workspace' 객체 자체에서'Dispose '를 호출해야합니다. –