【问题标题】:C++ - How to return list of covariant classes?C ++ - 如何返回协变量类列表?
【发布时间】:2020-06-20 18:19:37
【问题描述】:

我正在处理 Qt + C++ (x11)。

我有一个基类和几个返回指向该子类的新指针(协变)的子类。我也需要返回这些子类的容器(一个 QList)。一个例子:

class A
{
public:
    int id;
}

class B : public A
{
    int Age;
};

class WorkerA
{
public:
    virtual A *newOne() {return new A()};
    virtual QList<A*> *newOnes {
        QList<A*> list = new QList<A*>;
        //Perform some data search and insert it in list, this is only simple example. In real world it will call a virtual method to fill member data overriden in each subclass.
        A* a = this.newOne();
        a.id = 0;
        list.append(this.newOne()); 
        return list;
        };        
};

class WorkerB
{
public:
    virtual B *newOne() override {return new B()}; //This compiles OK (covariant)
    virtual QList<B*> *newOnes override { //This fails (QList<B*> is not covariant of QList<A*>)
        (...)
        };        
};

这将无法编译,因为 QList 是与 QList 完全不同的类型。但是类似的东西会很好。在现实世界中,B 会比 A 拥有更多的数据成员,并且会有 C、D...,因此需要对列表的返回进行“协变”。我会更好:

WorkerB wb;
//some calls to wb...
QList<B*> *bList = wb.newOnes();
B* b = bList.at(0); //please excuse the absence of list size checking
info(b.id);
info(b.age);

WorkerB wb;
//some calls to wb...
QList<A*> *bList = wb.newOnes();
B* b = static_cast<B*>(bList.at(0)); //please excuse the absence of list size checking
info(b.id);
info(b.age);

有什么办法可以做到吗?

【问题讨论】:

  • 我总是使用指向基类A 的指针。换句话说,使用多态性。

标签: c++ qt c++11


【解决方案1】:

我希望你能从下面提到的代码中得到一些关于这个问题的提示。

这里是 main.cpp:

#include <QCoreApplication>
#include <QDebug>
#include "myclass.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyClass mClass;
    mClass.name = "Debussy";

    // put a class into QVariant
    QVariant v = QVariant::fromValue(mClass);

    // What's the type?
    // It's MyClass, and it's been registered 
    // by adding macro in "myclass.h"
    MyClass vClass = v.value<MyClass>();

    qDebug() << vClass.name;  

    return a.exec();
}

【讨论】:

  • 我认为您将“协变”与“变体”混淆了。我真正需要的是从 QList 到 QList 的一些快速转换,而不必在每个子类中重新实现整个相同的方法。这是因为我将管理 QList 的几个变量,每个“class*”都是一个子类;并且不得不连续地做 static_cast 真的很乏味。
  • @Bull 并且不得不连续地做 static_cast 真的很乏味。同意。 (我从自己的经验中知道这一点。)使用class B: public class A { }; 并知道QList&lt;A*&gt; listA; 将只包含B* 的实例,你可以做一个QList&lt;B*&gt; &amp;listB = (QList&lt;B*&gt;&amp;)listA; 我相信编译器会“吃掉”这个,它甚至可以工作. 然而,它实际上是U.B. 你的乏味方式是唯一正确的恕我直言。 Demo on coliru(请注意编译器投诉。)
猜你喜欢
  • 1970-01-01
  • 2011-02-10
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
  • 1970-01-01
  • 2011-09-02
  • 2017-02-28
  • 1970-01-01
相关资源
最近更新 更多