如何通过抽象父类上的指针初始化子类?

时间:2019-06-10 18:01:33

标签: c++ c++11 pointers qdatastream

所以我是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方法!

2 个答案:

答案 0 :(得分: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。但正如我所说;不简单。

答案 1 :(得分:0)

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