我目前正致力于[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 基于继承的接口实现
可以基于OMG IDL接口定义从生成的基类派生实现类。生成的基类称为骨架类,派生类称为实现类。
所以对于C ++来说,“可以”不是“必须”,在C ++ 11之前,映射,并且给出的片段与此“can”一致
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 ++语言映射。 OMG,2012。http://www.omg.org/spec/CPP/1.3
[OMG13]天啊。 C ++ 11语言映射。 OMG,2013。http://www.omg.org/spec/CPP11/答案 0 :(得分:1)
CORBA :: servant_traits :: base_type应该在编译时解析为A_skel。用户并没有真正看到A_skel,这只是一个实现细节。用户定义的A_impl不仅仅是从CORBA :: servant_traits :: base_type trait派生的。
正如您所指出的,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版本中解决该问题
答案 1 :(得分:0)
回应Johnny Willemsen的回答:
好的,让我们将各个部分捆绑在一起:
标准要求
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 {};
然后必须有template<T>struct CORBA::servant_traits
的A的专门化,所以我认为,标准应该暗示这种依赖:
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() {}
我能做到这一点吗?