代码之家  ›  专栏  ›  技术社区  ›  Bull

C++-如何返回协变类列表?

  •  0
  • Bull  · 技术社区  · 5 年前

    我正在处理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);
    

    有什么方法可以实现这一点吗?

    0 回复  |  直到 5 年前
        1
  •  0
  •   Scheff's Cat    5 年前

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

    这里是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();
    }