Вектор виртуального класса: указатели — это чистый путь?

Замечания:
Это почти копия этой записи:
Абстрактные классы и указатели

Мне нужно создать вектор виртуальных классов. Здесь идея:

#include <vector>
using namespace std;

class VirtualFoo {
protected:
VirtualFoo();
virtual ~VirtualFoo();
public:
virtual void doStuff()=0;
};

class ConcreteFoo: public VirtualFoo {
public:
ConcreteFoo(double a);
virtual ~ConcreteFoo();
void doStuff();
private:
double a;
};

class Foo {
public:
Foo(std::vector<VirtualFoo> foos);
virtual ~Foo();
void doAllStuff();
protected:
std::vector<VirtualFoo> foos;
};

И я хотел бы использовать это так:

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

std::vector<ConcreteFoo> cfoos;
cfoos.push_back(ConcreteFoo(1.0));
cfoos.push_back(ConcreteFoo(2.0));

Foo foo = Foo(cfoos);
foo.doAllStuff();

}

Конечно, это не работает, потому что cfoos — это вектор VirtualFoo, а не ConcreteFoo.

Теперь, если я не использую вектор VirtualFoo, но вектор VirtualFoo * и отодвигаю указатели на экземпляры ConcreteFoo, это, кажется, работает нормально.

Просто я не уверен, что это самый чистый путь. Это больше похоже на то, что я не думал ни о каком другом способе сделать это. Это нормально?

1

Решение

Вектор с указателями std::vector<VirtualFoo*> cfoos; Это хорошо. Вы не можете создавать экземпляры абстрактных классов, поэтому компилятору не удается создать экземпляр или специализировать векторный шаблон, который использует абстрактный класс в качестве значения. Указывать элементы указателями базового класса — это нормально, это принцип подстановки Лискова (http://en.wikipedia.org/wiki/Liskov_substitution_principle)

Я согласен с комментариями других, что общие указатели являются лучшим решением, так что вам не нужно беспокоиться об управлении памятью:

std::vector<shared_ptr<VirtualFoo>> cfoos;
cfoos.push_back( shared_ptr<VirtualFoo> (new ConcreteFoo(1.0)) );
cfoos.push_back( shared_ptr<VirtualFoo> (new ConcreteFoo(2.0)) );
1

Другие решения

Других решений пока нет …