【问题标题】:c++ sealed and interfacec++ 密封和接口
【发布时间】:2010-11-29 13:28:04
【问题描述】:

我注意到 C++ 中有密封和接口关键字。这仅适用于 CLR C++ 吗? 如果没有,什么时候密封和接口被添加到 C++ 标准中?它们在 C++ 中的含义与在 C# 中的含义相同吗?如果没有,我如何在标准 C++ 中获得等价物?

【问题讨论】:

    标签: c++-cli sealed


    【解决方案1】:

    sealedinterface 关键字仅适用于 C++/CLI。详情请见Language Features for Targeting the CLR

    在标准 C++ 中,interface 可以替换为纯虚拟类和多重继承。 Sealed 关键字可以替换为 boost::noninheritable(这还不是 boost 的官方部分)。

    【讨论】:

    • 注意:如果您愿意使用 MS 扩展,sealed 可以在本机 C++ 代码中使用。感谢指向 boost::noninheritable 的指针。
    • 我不建议在本机 C++(即使在 Visual C++)中使用 sealed 关键字,因为该关键字不是 C++ 标准的一部分。
    • @Michael:如果它需要扩展,它就不是原生的。我想说 tuo 可以在 MS C++/CLI 代码中使用密封。这与 C++ 不太一样。
    • @Martin - 'native' 表示 x86/x64 目标,而不是 .NET 目标。有很多扩展适用于非 .NET C++ 程序(即使在非 Windows 平台上或使用非 MS 编译器。GCC 有很多自己的扩展)。我同意(并指出)它是一个非标准关键字,但专门使用 MSVC 的人可能会从中找到价值,就像他们可能会在 GCC 中发现 __declspec 有用或 typeof 一样。
    • 正如所指出的,interface 行为可以通过pure virtual functions 来实现,同样可以实现sealed,尤其是为了避免继承 C++11 引入了final 关键字
    【解决方案2】:

    interface 可以在 C++ 中使用纯虚拟类复制,利用您可以进行多重继承这一事实。

    sealed 可以使用私有构造函数和一种工厂模式(以实际获取密封类的实例)。 the C++ FAQ Lite 上还有几个其他示例。

    【讨论】:

    • 如何在 C++(标准 C++)中密封一个副本,有没有办法?
    • 根据大多数定义,mixin 实现了一些要添加到类中的行为,而不是接口。
    【解决方案3】:

    interfacesealed 由 MS 添加用于 C++/CLI 实现。但是,当前版本的 Microsoft 编译器也可以使用 support the sealed keyword for native code - 但这是您可能永远无法在其他地方找到的扩展。

    请注意,MS 对override 做了类似的事情——它是 MSVC 中的关键字扩展,表示函数旨在覆盖基类虚函数(如果事实并非如此,编译器会抱怨)。

    出于某种原因,Microsoft 没有为 interface 关键字做同样的事情,但他们确实有 __interface 关键字扩展,可以满足您的预期。我怀疑他们没有添加本机 interface 关键字扩展,因为在许多现有代码中都可以找到 interface 标识符(可能是解析为 class 的宏)——但这只是我的猜测.

    __interface 有下划线而sealedoverride 没有下划线的另一个因素可能是因为后者是"context-sensitive keywords" - MS 在 C++/CLI 中引入的一种技术,它使某些标识符仅在某些语法上下文 - 所以sealedoverride 仍然可以用作变量或函数名称,即使它们也用作关键字。编译器可以根据上下文确定哪种使用是合适的。也许他们无法为interface 解决这个问题。

    无论如何,您可以通过以下方式获得两全其美:

    #if _MSC_VER >= 1400
    #define OVERRIDE override
    #define SEALED sealed
    #define INTERFACE __interface
    #else
    #define OVERRIDE
    #define SEALED
    #define INTERFACE class
    #endif
    

    这是我公然偷的:

    【讨论】:

    • +1 帮助我弄清楚为什么我的 C++/CLI 代码使用 interface 作为标识符没有编译。这确实是一个宏。输入#undef interface,果然编译得很好。
    【解决方案4】:

    sealedinterface 不在 C++ 标准中。但是,C++11 添加了一个上下文 final 关键字,其语义与 Microsoft 的 sealed 关键字相同:

    // 'final' works on methods.
    class Base
    {
      public:
        virtual void foo() final { }
    };
    // This is an error in C++11:
    class Derived1 : public Base
    {
      public:
        // Error: Base's foo is final
        virtual void foo() { }
    };
    
    // 'final' also works on individual virtual methods.
    class FinalBase final { };
    // This is an error in C++11:
    class Derived2 : public FinalBase { };
    

    由于对可移植性进行了一些次要的宏抽象,我认为今天没有理由不使用sealed,如果它有帮助并且您使用支持它的编译器(或其标准化的final 同义词)定期编译。

    【讨论】:

      【解决方案5】:

      __interface 自 VS 2005 起在 Visual C++ 中有效。它提供了额外的编译时验证,使界面看起来和闻起来都应该。 (链接的 MSDN 文章有完整的详细信息。)

      但是,__sealed 似乎只是“C++ 托管扩展”的一部分。

      【讨论】:

      • __interface__sealed 来自旧语法。你不应该使用它们。
      • __sealed 是旧的,是的。但是__interface?它被非托管世界中的任何东西取代了吗?
      • 对不起,__interface 仍然用于非托管接口。从未使用过它:) 但它与 C++/CLI 无关,也不是 C++ 标准。在托管世界中,应使用sealedinterface,不带前导下划线。
      猜你喜欢
      • 2011-07-20
      • 1970-01-01
      • 2021-11-05
      • 1970-01-01
      • 1970-01-01
      • 2020-03-01
      • 1970-01-01
      • 2022-07-22
      • 1970-01-01
      相关资源
      最近更新 更多