- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在使用 C++/CLI,使用 MSDN 文档和 ECMA standard和 Visual C++ Express 2010。让我印象深刻的是以下与 C++ 的背离:
For ref classes, both the finalizer and destructor must be written so they can be executed multiple times and on objects that have not been fully constructed.
#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
}
#1
,自动变量
x
死亡,并调用析构函数(它依次显式调用终结器,就像通常的习惯用法一样)。这一切都很好。但是后来我通过引用再次删除了对象
r
!输出是这样的:
Foo()
~Foo()
!Foo()
~Foo()
!Foo()
delete r
是未定义的行为,还是完全可以接受?在线#2
? #2
,这有关系吗r
仍然是(在 C++ 意义上)不再存在的对象的跟踪句柄?是“悬空 Handlebars ”吗?它的引用计数是否意味着会尝试双重删除?Foo()
~Foo()
!Foo()
x.~Foo();
可以吗紧接在之前或之后 r = %x;
? ref struct Foo
{
Foo()
: p(new int[10])
, a(gcnew cli::array<int>(10))
{
std::wcout << L"Foo()\n";
}
~Foo()
{
delete a;
a = nullptr;
std::wcout << L"~Foo()\n";
this->!Foo();
}
!Foo()
{
delete [] p;
p = nullptr;
std::wcout << L"!Foo()\n";
}
private:
int * p;
cli::array<int> ^ a;
};
最佳答案
我将尝试按顺序解决您提出的问题:
For ref classes, both the finalizer and destructor must be written so they can be executed multiple times and on objects that have not been fully constructed.
~Foo()
简单地自动生成两个方法,一个 IDisposable::Dispose() 方法的实现以及一个实现一次性模式的 protected Foo::Dispose(bool) 方法。这些是普通方法,因此可以多次调用。 C++/CLI 允许直接调用终结器,
this->!Foo()
并且通常完成,就像您一样。垃圾收集器只调用一次终结器,它会在内部跟踪是否已完成。鉴于允许直接调用终结器并且允许多次调用 Dispose(),因此可以多次运行终结器代码。这是特定于 C++/CLI 的,其他托管语言不允许。您可以轻松阻止它,nullptr 检查通常可以完成工作。
Is it undefined behavior, or is it entirely acceptable, to call delete r on line #2?
delete
运算符只需调用 IDisposable::Dispose() 方法,从而运行您的析构函数。您在其中所做的事情,通常是调用非托管类的析构函数,很可能会调用 UB。
If we remove line #2, does it matter that r is still a tracking handle
Under which other circumstances can the destructor of a managed object be called more than once?
using (var fs = new FileStream(...))
using (var sw = new StreamWriter(fs)) {
// Write file...
}
Would it be OK to insert x.~Foo(); immediately before or after r = %x;?
In other words, do managed objects "live forever"
Code snippet
a
object 是不必要的,没有效果。您只能删除实现 IDisposable 的对象,数组不会这样做。通用规则是 .NET 类仅在管理内存以外的资源时才实现 IDisposable。或者,如果它有一个本身实现 IDisposable 的类类型的字段。
关于c++ - C++/CLI 中的重复析构函数调用和跟踪句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12240297/
我设置了 Helm 柄和 Helm 柄。我有tiller-deploy。昨天,我可以定期运行了。但今天我收到此错误消息 Error: could not find a ready tiller pod
我以前已将分er安装到特定的 namespace 中。 我设置了一个环境变量来设置'tiller'命名空间-但我不记得该环境变量的名称-而且似乎无法通过网络搜索找到它。 这是什么 key ? 最佳答案
当我在 View 模型中使用如下界面时 class MainViewModel @ViewModelInject constructor( private val trafficImagesR
我正在尝试找到如何在某个 fragment 相关场景中定义 Hilt 的解决方案。我有以下设置: Activity 父 fragment 1 子 fragment 1 子 fragment 2 ...
Hilt 指出如果没有@Provides 注解就不能提供这个接口(interface): interface PlannedListRepository { fun getAllLists()
我的问题非常简单明了:两个注释/示例之间有什么区别: 例子一 @Singleton class MySingletonClass() {} @Module @InstallIn(FragmentCom
我是一名优秀的程序员,十分优秀!