我正在使用C++/CLI,使用MSDN文档和ECMA标准以及Visual C++ Express 2010.令我震惊的是以下与C++的不同之处:
对于ref类,必须编写终结器和析构函数,以便可以多次执行它们以及尚未完全构造的对象.
我编造了一个小例子:
#include <iostream>
ref struct Foo
{
Foo() { std::wcout << L"Foo()\n"; }
~Foo() { std::wcout << L"~Foo()\n"; this->!Foo(); }
!Foo() { std::wcout << L"!Foo()\n"; }
};
int main()
{
Foo ^ r;
{
Foo x;
r = %x;
} // #1
delete r; // #2
}
Run Code Online (Sandbox Code Playgroud)
在块的末尾#1,自动变量x死亡,并且析构函数被调用(它反过来调用终结器,就像通常的习惯用法一样).这一切都很好.但后来我通过引用再次删除了该对象r!输出是这样的:
Foo()
~Foo()
!Foo()
~Foo()
!Foo()
Run Code Online (Sandbox Code Playgroud)
问题:
delete r在线呼叫是不确定的行为,还是完全可以接受#2?
如果我们删除行#2,那么r对于一个(在C++意义上)不再存在的对象的跟踪句柄是否重要?这是一个"晃来晃去的手柄"吗?它的引用计数是否会导致尝试双重删除?
我知道没有实际的双删除,因为输出变为: …