0

我目前正在开发符合 [OMG13](如下)的 C++11 部分外观,以适应旧版 (C++)ORB;“部分”在服务器端的意义上,没有 DII,没有 OBV 等 - 因此只是非常基本的东西。

[OMG13] 6.25.6中有基于继承的接口实现

实现必须从基于 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 Inheritance-Based Interface Implementation

实现类可以从基于 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] 并强化 impl 代码以防止可能重构 [OMG13] 的那部分?

例如,可以考虑从 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++ 语言映射。天哪,2012。http ://www.omg.org/spec/CPP/1.3

[OMG13] 我的天啊。C++11 语言映射。天哪,2013。http ://www.omg.org/spec/CPP11/

4

2 回答 2

1

CORBA::servant_traits::base_type 应该在编译时解析为 A_skel。用户并没有真正看到 A_skel,这只是一个实现细节。用户定义的 A_impl 不仅仅是从 CORBA::servant_traits::base_type 特征派生的。

正如您所指出的,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。我们也可以协助您应对挑战,请随时直接与我联系。

您能否向 OMG 报告 6.26.2 中示例的正式问题,以便我们可以在 V1.2 版本的规范中解决该问题

于 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 回答