0

私は現在、レガシー (C++) ORB を適応させるための [OMG13] (以下) 準拠の C++11 部分ファサードに取り組んでいます。サーバー側、DII、OBV などがないという意味での「部分的」 - したがって、非常に基本的なもののみです。

[OMG13] has in 6.25.6 Inheritance-Based Interface Implementation

実装は、OMG IDL インターフェイス定義に基づいて生成された基本クラスから派生する必要があります。生成された基本クラスはスケルトン クラスと呼ばれ、派生クラスは実装クラスと呼ばれます。インターフェイスの各操作には、スケルトン クラスで宣言された対応する仮想メンバー関数があります。

[強調鉱山]

文字どおりに解釈すると、idl で定義されたインターフェイス A の場合、A_impl は A_skel の子孫でなければならないことを意味します。

class A_impl : /* whatever, likely public */  A_skel {
    /**/
};

しかし、6.25.6で与えられたスニペットはそうではないことを示しています

// C++
class A_skel : public virtual CORBA::servant_traits<A>::base_type { ... };
// C++
class A_impl: public virtual CORBA::servant_traits<A>::base_type { ... };

したがって、スニペットによると、A_impl と A_skel は兄弟であり、同じ祖先から派生しています。


前者の標準、C++11 より前の C++、マッピング [OMG12] には5.40.3継承ベースのインターフェイス実装があるため、何をすべきかを決定するのは簡単ではありません。

実装クラスは、OMG IDL インターフェイス定義に基づいて生成された基本クラスから派生できます。生成された基本クラスはスケルトン クラスと呼ばれ、派生クラスは実装クラスと呼ばれます。

したがって、C++ では、C++11 より前のマッピングでは「できる」ではなく「しなければならない」ではなく、で指定されたスニペットはこの「できる」と一致しています。

class POA_A : public virtual PortableServer::ServantBase 
{
    /* [...] */
}

/* [...] */

class A_impl : public POA_A
{
   /* [...] */
};

そしてそれは、私が取り組んでいる従来の ORB のインフラストラクチャが構築されているものでもあります ([OMG12] 準拠の委任ベースの実装も提供することは別として)。


では、私の小さな C++11 準拠の ORB ファサードで _skel と _impl を関連付けて [OMG13] に準拠し、[OMG13] のその部分のリファクタリングの可能性に対して impl コードを強化するにはどうすればよいでしょうか?

たとえば、CRTP スタイルの継承多重化クラスから _impls を派生させることを検討できます。

struct Snippet_Reading{};
struct Prose_Reading{};

namespace mock {

    class IA{}; 

    // impl specific, not important here  
    template<class Ifc>
    struct LoremIpsum {}; 


    template<class Ifc>
    class POA_Delegator {
         // impl specific, not important here  
    };

    namespace CORBA {
        template<class Ifc>
        struct servant_traits {
            /// @TODO meditate how to implement that
            typedef LoremIpsum<Ifc> base_type;
        };
    }
} 

namespace detail {
    using namespace mock;

    template<typename Reading, class Ifc>
    class Base {};

    template<class Ifc>
    class Base<Prose_Reading, Ifc> : public virtual POA_Delegator<Ifc> {};

    template<class Ifc>
    class Base<Snippet_Reading, Ifc> : public virtual CORBA::servant_traits<Ifc>::base_type {};
}

#if defined(PROSE_READING)
    template <class Ifc>
    using Base = detail::Base<Prose_Reading, Ifc>;
#elif  defined(SNIPPET_READING)
    template <class Ifc>
    using Base = detail::Base<Snippet_Reading, Ifc>;
#else
    #error Oh My Goodness! Don't know how to interpret OMG's IDL to C++11 Mapping!
#endif 


class IA_impl : public virtual Base<mock::IA> {};


int main() {}

しかし、これは正確に標準準拠の実装者のインターフェースを生み出すわけではありません。

参考文献

[OMG12] OMG C++ 言語マッピング。OMG、2012年。http://www.omg.org/spec/CPP/1.3

[OMG13] OMG。C++11 言語マッピング。OMG、2013年。http://www.omg.org/spec/CPP11/

4

2 に答える 2

1

CORBA::servant_traits::base_type は、コンパイル時に A_skel に解決される必要があります。ユーザーは実際には A_skel を見ていません。これは単なる実装の詳細です。CORBA::servant_traits::base_type トレイトから派生しただけでなく、ユーザーが A_impl を定義しました。

ご指摘のとおり、6.26.6に誤りがあります。スケルトン クラスは、トレイトからではなく、相互に派生する必要があるため、次のようになります。また、C_skel が不足しています。

// C++
class A_skel : public virtual PortableServer::ServantBase {};
class B_skel : public virtual A_skel {};
class C_skel : public virtual A_skel {};
class D_skel : public virtual B_skel, public virtual C_skel {};

ドラフト V1.1 マッピングについては、http://osportal.remedy.nl を参照してください。また、あなたの挑戦を支援することもできます。お気軽に私に直接お問い合わせください。

仕様の V1.2 バージョンで解決できるように、6.26.2 の例について正式な問題を OMG に報告していただけますか。

于 2013-06-05T13:52:45.620 に答える
0

ジョニー・ウィレムセンの答えに応えて:

では、ピースをつなぎ合わせましょう:

標準的な要求

class A_impl: public virtual CORBA::servant_traits<A>::base_type { ... };

そしてこれなら

CORBA::servant_traits::base_type は、コンパイル時に A_skel に解決される必要があります。

このように定義された A_skel に適用されます

class A_skel : public virtual PortableServer::ServantBase {};

次に、 A of の特殊化が必要なtemplate<T>struct CORBA::servant_traitsので、私はそれを採用します。標準は、この種の依存関係を暗示します。

class A {
  public:
    virtual long foo() = 0;
};

namespace mock {

    namespace CORBA {
        template<class Ifc>
        struct servant_traits { /* ? */};
    }

    namespace PortableServer {
        class ServantBase { /* ... */};
    }
} 

using namespace mock;

class A_skel : public virtual PortableServer::ServantBase {
    virtual long foo() = 0;
};

namespace mock {
    namespace CORBA {
        template<>
        struct servant_traits<A> {
            typedef A_skel base_type;
            // ...
        };
    }
}    

class A_impl : public virtual CORBA::servant_traits<A>::base_type {
  public:
    virtual long foo() {
        return 42;
    }
};

int main() {}

私はこれを正しく理解していますか?

于 2013-06-06T13:32:57.690 に答える