我目前正在开发一个兼容OMG13的C++11部分外观,用于调整遗留(C++)ORB;“部分”的意义只是服务器端,没有DII,没有OBV等等,因此只有非常基本的内容。
OMG13在6.25.6中有基于继承的接口实现
实现必须来自基于OMG接口定义的生成的基类。生成的基类称为骨架类,派生类称为实现类。接口的每个操作都有一个对应的在骨架类中声明的虚拟成员函数。
重点地雷
如果从字面上看,这意味着对于定义在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++在C++11之前的映射OMG12,它有基于5.40.3 继承的接口实现
实现类可以从基于OMG接口定义的生成基类派生。生成的基类称为骨架类,派生类称为实现类。
因此,对于C++,在C++11之前,映射是"can“而不是”必须“,并且所给出的片段与此"can”一致。
class POA_A : public virtual PortableServer::ServantBase
{
/* [...] */
}
/* [...] */
class A_impl : public POA_A
{
/* [...] */
};这也是我所使用的遗留ORB构建的基础设施(除了提供符合OMG12 12的基于委托的实现之外)。
So -如何在我的小c++11-遵从ORB外观中将_skel和_impl联系起来,使其符合of 13,并且增强了_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 OMG.C++11语言映射OMG,2013年。http://www.omg.org/spec/CPP11/
发布于 2013-06-05 13:52:45
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。我们也可以协助您的挑战,随时与我直接联系。
您能否就6.26.2中的示例向OMG报告一个正式问题,以便在规范的V1.2版本中解决这个问题?
发布于 2013-06-06 13:32:57
针对约翰尼·威勒姆森的回答:
好吧,让我们把这些碎片绑在一起:
标准要求
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() {}我说得对吗?
https://stackoverflow.com/questions/16941484
复制相似问题