如果我编译并运行以下内容:
using namespace System;
ref class C1
{
public:
C1()
{
Console::WriteLine(L"Creating C1");
}
protected:
~C1()
{
Console::WriteLine(L"Destroying C1");
}
};
int main(array<System::String ^> ^args)
{
C1^ c1 = gcnew C1();
delete c1;
return 0;
}...the代码编译时没有错误,并运行给我以下内容:
Creating C1
Destroying C1
Press any key to continue . . .如果我在C++中做了同样的事情,我会得到一个错误,如下所示:
1>ProtectedDestructor.cpp(45): error C2248: 'C1::~C1' : cannot access protected member declared in class 'C1'
1> ProtectedDestructor.cpp(35) : compiler has generated 'C1::~C1' here
1> ProtectedDestructor.cpp(23) : see declaration of 'C1'...so为什么它在CLI中有效?
发布于 2015-04-13 14:01:42
这是一个漏洞百出的抽象问题。C++/CLI中有几个,我们已经经历了const关键字问题。在这里,运行时没有任何析构函数的概念,只有终结器是真实的。所以它必须是伪造的。创建这种错觉非常重要,本地C++中的RAII模式是神圣的。
它是通过在IDisposable接口上插入析构函数的概念来伪造的。使确定性破坏在.NET中工作的方法。非常常见的是,C#语言中的using关键字会调用它。在C++/CLI中没有这样的关键字,您可以使用delete操作符。就像在本地C++中一样。编译器也会提供帮助,在使用堆栈语义时会自动发出析构函数调用。就像原生C++编译器所做的那样。救RAII。
不错的抽象概念,但是的,它泄露了。问题是接口方法总是公开的。从技术上讲,通过显式接口实现使其成为私有是可能的,尽管它只是一种权宜之计:
public ref class Foo : IDisposable {
protected:
//~Foo() {}
virtual void Dispose() = IDisposable::Dispose {}
};生成一个非常令人印象深刻的错误列表,当您尝试这样做时,编译器会尽力反击:)。C2605是唯一相关的:"'Dispose':此方法是在托管类中保留的“。当你这样做的时候,它无法维持幻觉。
长话短说,IDisposable::Dispose()方法实现总是公开的,而不管析构函数的可访问性如何。delete操作符调用它。解决不了这个问题。
https://stackoverflow.com/questions/29603291
复制相似问题