为什么不保护C ++ - Cli析构器导致编译错误? [英] Why don't protected C++-Cli destructors cause compilation errors?

查看:225
本文介绍了为什么不保护C ++ - Cli析构器导致编译错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我编译并运行以下命令:

If I compile and run the following:

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;
}

...代码编译时没有错误,并运行: / p>

...the code compiles without an error and runs giving me this:

Creating C1
Destroying C1
Press any key to continue . . .

如果我在C ++中也是这样,我得到以下行的错误:

If I do the same in C++ I get an error along the following lines:

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'

...为什么它是有效的in CLI?

...so why is it valid in CLI?

推荐答案

这是一个泄漏抽象问题。 C ++ / CLI有其中几个,我们已经经历了 const 关键字问题。在这里大致相同,运行时没有析构函数的任何概念,只有终结器是真实的。所以它必须伪造。这是非常重要的创建这个错觉,RAII模式在本机C + +是神圣的。

This is a leaky abstraction problem. C++/CLI has several of them, we already went through the const keyword problem. Much the same here, the runtime does not have any notion of a destructor, only the finalizer is real. So it has to be faked. It was pretty important to create that illusion, the RAII pattern in native C++ is holy.

这是伪造的,通过在IDisposable接口顶部的析构函数的概念。使确定性破坏在.NET中工作的那个。很常见,例如使用C#语言中的使用关键字调用它。在C ++ / CLI中没有这样的关键字,您使用 delete 运算符。就像你在本机C ++。编译器帮助,当你使用堆栈语义时,自动发出析构函数调用。就像一个本地的C ++编译器。救援RAII。

It is faked by bolting the notion of a destructor on top of the IDisposable interface. The one that makes deterministic destruction work in .NET. Very common, the using keyword in the C# language invokes it for example. No such keyword in C++/CLI, you use the delete operator. Just like you would in native C++. And the compiler helps, automatically emitting the destructor calls when you use stack semantics. Just like a native C++ compiler does. Rescuing RAII.

体面抽象,但是,它泄漏。问题是接口方法总是public。从技术上讲,可以通过显式的接口实现来实现它,虽然它只是一个障碍:

Decent abstraction, but yes, it leaks. Problem is that an interface method is always public. It is technically possible to make it private with explicit interface implementation although it is but a stopgap:

public ref class Foo : IDisposable {
protected:
    //~Foo() {}
    virtual void Dispose() = IDisposable::Dispose {}
};

当你尝试这个时,产生一个非常令人印象深刻的错误列表,编译器尽可能地回击: )。 C2605是唯一相关的一个:'Dispose':这个方法在托管类中保留。

Produces a very impressive error list when you try this, the compiler fights back as hard as it can :). C2605 is the only relevant one: "'Dispose': this method is reserved within a managed class". It can't maintain the illusion when you do this.

很长的故事,IDisposable :: Dispose()方法实现总是公开的,不管析构函数。 delete 运算符调用它。此方法无此解决方法。

Long story short, the IDisposable::Dispose() method implementation is always public, regardless of the accessibility of the destructor. The delete operator invokes it. No workaround for this.

这篇关于为什么不保护C ++ - Cli析构器导致编译错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆