-1

所以我是 C++ 新手,我的问题是这个:我有一个抽象类,它作为多个子类(它们也有其他子类)。我正在尝试使用多态性来序列化和反序列化这些子类,并且在我的抽象类中具有:

    virtual QDataStream& serialize(QDataStream& stream)=0;
    virtual QDataStream& deserialize(QDataStream &stream)=0;

所以我的问题很简单:当我反序列化时,我想调用反序列化函数,但我还不知道我正在检索哪个子类。

函数是这样的:

QDataStream& operator>>(QDataStream& in, SomeClass& i){

    std::shared_ptr<AbstractClass> ptr;
    ptr->deserialize(in); //Raises an SIGSEGV error

}

我不知道我是否完全清楚,但基本上我要做的是实例化并调用流对应的任何子类,然后调用反序列化。可能吗 ?

谢谢!

编辑:我的第一种方法是同时提供 QDataStream 我的子类名称,以便我知道要实例化哪个类:

        QString myClassName;
        in >> myClassName;
        if(myClassName == "ChildClass1"){
            std::unique_ptr<AbstractClass> ptr(new ChildClass1);
            ptr->deserialize(in);
        }

但我觉得这真的不是一个干净的 OOP 方式!

4

2 回答 2

0
 std::shared_ptr<AbstractClass> ptr;

默认初始化的共享指针指向 null。

通过空指针间接进行的行为是未定义的。

ptr->deserialize(in); //Raises an SIGSEGV error

这通过空指针间接。程序的行为是未定义的。


您可以通过摆脱动态分配来简化您的工作示例:

ChildClass1 c;
c.deserialize(in);

在这种情况下,您不需要多态性。


我要做的是实例化并调用任何子类[在运行时确定]

您在这里尝试实现的本质上是工厂方法模式。在静态类型的非反射语言(例如 C++)中,没有简单的方法可以以通用方式实现工厂方法。您会发现大多数示例都使用一种简单的 if-else 结构,例如您自己建议的结构。

您可以在另一篇文章中看到一些创建通用工厂方法的尝试,这个答案似乎特别合适:https ://stackoverflow.com/a/17408318/2079303 。但正如我所说;不简单。

于 2019-06-10T18:07:11.150 回答
0

不幸的是,仅从基类初始化子类是不可能的。序列化时,您必须为子类序列化某种 id。接下来反序列化时我建议你使用工厂模式。使用工厂传递您希望反序列化的 id 和类数据。该工厂函数将构造所需的子类并返回一个指向基类的指针。

于 2019-06-10T18:15:43.493 回答