виртуальная функция с вектором пользовательского типа - PullRequest
1 голос
/ 12 апреля 2011

Я хочу определить абстрактный базовый класс с вектором переменных структуры и виртуальную функцию для реализации производными классами:

class TestFather {

private:
    struct myStruct
    {
        // struct definition
    };
    vector<myStruct> myStructVect;

public:
    virtual vector<myStruct> get_myStructVect() = 0;
};

но когда я пишу производный класс:

#include "TestFather.h"

class TestSon : public TestFather{

private:
    struct myStruct
    {
        // struct definition
    };
    vector<myStruct> myStructVect;

public:
    vector<myStruct> get_myStructVect();
};

Я получаю эту ошибку:

invalid covariant return type for ‘virtual std::vector<ProvaSon::myStruct, std::allocator<ProvaSon::myStruct> > ProvaSon::get_myStructVect()’

Я делаю что-то не так или, может быть, я пытаюсь сделать что-то, что запрещено языком?

Ответы [ 5 ]

4 голосов
/ 12 апреля 2011

Два типа myStruct абсолютно не связаны. Это означает, что вы пытаетесь переопределить TestFather::get_myStructVect() и заставить его вернуть совершенно другой тип. Это не разрешено.

3 голосов
/ 12 апреля 2011

Вам не нужно переопределять структуру в TestSon, и вы также не можете этого сделать. Вызывающий fatherptr->get_myStructVect статически получает обратно vector<TestFather::myStruct>, поэтому компилятор запрещает вам переопределять функцию базового класса, потому что динамически возвращаемый объект потенциально несовместим с vector<TestFather::myStruct> (кто знает, что вы положили в TestSon::myStruct а чем vector отличается по поведению от вектора базового класса?).

Что касается допустимого различия, C ++ допускает, чтобы возвращаемый тип производного класса был производным классом возвращаемого типа базового класса, и только тогда, когда возвращаемые типы являются указателями или ссылками.

2 голосов
/ 12 апреля 2011

Это говорит vector<myStruct>, но поскольку вы изменили myStruct в дочернем классе, на самом деле это два разных типа, поэтому каждая из двух функций думает, что она возвращает свой тип. Это разрешено только для ковариантных типов, где тип связан с фактическим типом класса, содержащего функцию.

Обратите внимание, что вам, вероятно, все равно не следует возвращать вектор атрибута класса по значению.

Я не могу сказать, что вы на самом деле намереваетесь делать, но вложенные структуры на самом деле не должны иметь одно и то же имя, если это две разные вещи (и если они одинаковые, не переопределяйте это) , Моя первая инстинктивная реакция заключается в том, что, возможно, отношения между родителями и детьми здесь неуместны. Рассматривали ли вы другие варианты? Если вам действительно нужно вернуть другой тип в дочерний элемент, и родитель не знает об этом, то вы не можете использовать виртуальный интерфейс для этого. Вам нужно просто дать функциям разные имена, чтобы вы знали, какой должен быть тип возвращаемого значения.

С более подробной информацией о ваших целях можно получить лучший ответ.

2 голосов
/ 12 апреля 2011

Это запрещено.Поскольку вы переопределили myStruct в своем производном классе, вектор - это другой тип в производном классе, чем в базовом классе.Это два разных myStructs.

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

1 голос
/ 12 апреля 2011

Двойная частная структура немного странная в вашем примере. Ниже компилируется нормально, например:

класс TestFather {

protected:
    struct myStruct
    {
        // struct definition
    };
    vector<myStruct> myStructVect;

public:
    virtual vector<myStruct> get_myStructVect() = 0;
};

class TestSon : public TestFather{



public:
    vector<myStruct> get_myStructVect();
};

int main(int argc, char**argv)
{
   TestSon testSon;
}

Обратите внимание на замену private закрытым защищенным, предоставляя производным классам доступ к определению родительской структуры и хранилищу myStructVect.

...