考虑以下课程:
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在下一次收集期间回收所有内存时,最有效和最优雅的方法是什么?我是否需要在每个成员上明确调用 delete 和/或将其重置为 nullptr ?
答案 0 :(得分:5)
NB。您可能不需要做任何事情。当引用不再存在指向它的引用时,GC将回收对象的内存。
只需在对象实现IDisposable
时显式回收。在C ++ / CLI中,这映射到析构函数。
因此,如果您要分配的对象都不需要处理,您可以忽略此答案的其余部分。但假设他们这样做......
从每个字段中删除^
,它们将自动回收。
这也意味着在构造Workspace
时它们将自动默认构造,这可能会在手写构造函数中为您节省大量gcnew
内容。
也就是说,如果你说:
Form WorkspaceUI;
然后你不需要说:
WorkspaceUI = gcnew Form();
编译器已经为你生成了 - 想象它是在构造函数的开头插入的。
您也不需要处置/删除任何内容。
最后,您需要使用.
而不是->
来访问以这种方式声明的对象的成员:
Form.Controls->Add(WorkspaceSplitter);
<强>更新强>
在C ++ / CLI中,使用^
声明ref类的句柄,这类似于使用*
声明指向本机类的指针的方式。
相应地,还需要一种获取对象句柄的方法。要获取指向本机对象的指针,我们前缀为&
。要获取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);
如果反复创建和删除班级中的对象会导致内存不足,则有两种可能:
Dispose
。如果是后者,在C ++ / CLI中有内置支持自动调用Dispose
- C ++ / CLI将一次性对象视为具有析构函数的C ++ ref类。
因此,如果删除句柄,则会在其指向的对象上调用Dispose
。
或者如果(如上所述)你只是拥有成员对象,你甚至不需要明确删除。当外部包含类被破坏时(即某个东西调用它的Dispose
方法),它会自动在需要它的任何成员对象上调用Dispose
。