Замечания:
Это почти копия этой записи:
Абстрактные классы и указатели
Мне нужно создать вектор виртуальных классов. Здесь идея:
#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, это, кажется, работает нормально.
Просто я не уверен, что это самый чистый путь. Это больше похоже на то, что я не думал ни о каком другом способе сделать это. Это нормально?
Вектор с указателями 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)) );
Других решений пока нет …