C ++ - Как вернуть список ковариантных классов? - PullRequest
0 голосов
/ 08 марта 2020

Я имею дело с 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);

Есть ли способ добиться этого?

1 Ответ

0 голосов
/ 08 марта 2020

Надеюсь, из приведенного ниже кода вы получите подсказку для этой проблемы.

Вот главная. 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...