Как реализовать функцию с вектором производных классов в качестве параметра - PullRequest
2 голосов
/ 26 ноября 2010

(относится к предыдущему неотвеченному вопросу я задал). Я хочу реализовать функцию, которая может вызываться только с векторами связанных классов в качестве параметра.

Для экв.

если у нас есть

class A;
class B: public A;
class C: public A;
class D

then it should be possible to call function with vector<A*>,vector<B*> or 
vector <C*> but not vector <D*>

Любые предложения

Ответы [ 2 ]

1 голос
/ 26 ноября 2010

Полагаю, вы уже пытались создать метод, подобный

void doSomething(std::vector<A*>& things)
{
}

, и пытались выполнить pass

std::vector<B*> bList = ...;
doSomething(bList);

правильно?

Почему компилятор жалуется?Потому что это не имеет смысла.Учтите, что doSomething () пытается сделать

things.push_back(new C());

Это не может работать, поскольку "вещи" на самом деле std::vector<B*>.Однако, если бы это было std::vector<A*>, push_back сработал бы.

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

Простая оболочка показывает возможное решение (конечно, оболочку можно настроить в соответствии с вашими потребностями).Однако я должен отметить, что использование виртуальных методов может привести к снижению производительности.

class A {};
class B : public A {};

template <class Base>
class AbstractVectorWrapper
{
public:
    virtual size_t size() const = 0;
    virtual Base* getElementAt(int index) const = 0;
};
template <class Base, class Derived>
class VectorWrapper : public AbstractVectorWrapper<Base>
{
private:
    std::vector<Derived*> m_vector;
public:
    explicit VectorWrapper(std::vector<Derived*> const& vector)
        : m_vector(vector)
    {
    }
    virtual size_t size() const
    {
        return m_vector.size();
    }
    virtual Base* getElementAt(int index) const
    {
        return m_vector[index];
    }
};

void doSomething(AbstractVectorWrapper<A> const& wrapper)
{
    for (size_t i=0;i<wrapper.size();i++)
    {
        A* a = wrapper.getElementAt(i);
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<A*> as;
    std::vector<B*> bs;
    doSomething(VectorWrapper<A,B>(bs));
    doSomething(VectorWrapper<A,A>(as));


    return 0;
}
1 голос
/ 26 ноября 2010

Достаточно ли для вас набора текста по утке ?Рассмотрим этот код

template <class T>
void my_function (std::vector <T*> const &values) {
    // Use features of A* here
}

Компиляция не удастся, если вы используете функции, которые не поддерживают указатели на T.Используя функции A, я думаю, следует гарантировать, что указатели на B и C также будут работать, как и ожидалось.Однако можно было бы вызвать эту функцию с векторами D *, при условии, что интерфейс D соответствует тому, что my_function пытается сделать.

...