【问题标题】:Convert Polymorphic C++ Object to Non-Polymorphic C Object将多态 C++ 对象转换为非多态 C 对象
【发布时间】:2015-09-24 14:19:36
【问题描述】:

这个奇怪问题的一点背景知识:我有一个网络框架 (RTI DDS),它有一个 C 序列化函数,它接受一个指针并将 C 结构转换为字符串。

它也(并且也设计用于)C++ 类。但是,如果我通过添加虚函数使 C++ 类具有多态性,则此序列化函数会出现段错误,有时甚至会提供错误的输出。

我假设它在内部对结构的内存布局做出了假设。

是否可以从多态 C++ 对象中获取原始 C 指针?

我知道我可以只创建每个结构两次,一次是多态的,一次是非多态的,但这会导致大量的胶水代码。

目前我没有想法。

一些技术背景:C 函数在 RTI DDS Source 包中:

DynamicData.c DDS_ReturnCode_t DDS_DynamicData_to_cdr_buffer(...) { ..

【问题讨论】:

  • 我不认为 vtable 实现是跨编译器的标准。我认为如果你想在运行时这样做,你必须知道你的班级的大小和确切的偏移量。只是我的逻辑猜测。
  • It also (and is also designed to work) with C++ classes 我很难相信。在 C++ 中,除非类/结构是标准布局,否则一旦开始弄乱数据的内部表示,就很容易进入 UB 领域。
  • 我猜,问题是那里的多态部分是什么。你需要它吗?如果你这样做了,我很难相信任何序列化技巧会帮助你,因为你会失去多态性。如果你不需要它,为什么你首先要有虚函数?
  • @SergeyA:DDS 中有某种联合类型。所以我把继承树中的所有类都填入了这个联合类型。然后我使用 typeid 将输入对象的类型与联合中的类进行比较,然后动态转换为正确的类型,然后将其序列化。

标签: c++ c pointers polymorphism data-distribution-service


【解决方案1】:

您可以添加仅包含数据的非虚拟基础struct

struct DataXYBase {
    int data1;
    double data2;
};

class VirtualBaseClass : public DataXYBase {
    virtual void Function1();
};

class DerivedClass : public VirtualBaseClass {
    virtual void Function1();
};

然后在传递给序列化函数之前转换为DataXYBase

【讨论】:

    【解决方案2】:

    我认为您应该将所有数据捆绑在 POD 结构中(它们可能可以相互继承)以及包含数据结构的多态类中的所有访问器/逻辑作为成员(或者甚至可能通过继承)。您将只序列化数据部分,并为来自数据结构的多态类提供简单的构造函数。

    这应该会限制必要的粘合量,并且仍然在您的代码中保留所需的多态性。

    【讨论】:

      猜你喜欢
      • 2012-10-21
      • 1970-01-01
      • 1970-01-01
      • 2016-08-02
      • 1970-01-01
      • 2013-05-15
      • 2016-04-24
      • 1970-01-01
      • 2018-03-16
      相关资源
      最近更新 更多