Чтобы получить наилучший ответ на этот вопрос, я объединяю все ответы.
Альтернативы google maps api:
Вы не можете создавать абстрактные классы, поэтому вектор абстрактных классов не может работать.
Однако вы можете использовать вектор указателей для абстрактных классов:
std::vector<IFunnyInterface*> ifVec;
Это также позволяет фактически использовать полиморфное поведение - даже если класс не был абстрактным, сохранение по значению привело бы к проблеме разбиения объектов .
Я думаю, что основной причиной этого действительно печального ограничения является тот факт, что конструкторы не могут виртуально. Вследствие этого компилятор не может сгенерировать код, который копирует объект, не зная его времени во время компиляции.
std :: vector попытается выделить память для хранения вашего типа. Если ваш класс является чисто виртуальным, вектор не может знать размер класса, который он должен будет выделить.
Я думаю, что с вашим обходным путем вы сможете скомпилировать vector<IFunnyInterface>
, но вы выиграли ' t иметь возможность манипулировать FunnyImpl внутри него. Например, если IFunnyInterface (абстрактный класс) имеет размер 20 (я действительно не знаю), а FunnyImpl имеет размер 30, потому что у него больше членов и кода, вы в конечном итоге попытаетесь поместить 30 в свой вектор из 20
Решение заключалось бы в том, чтобы выделить память в куче с помощью «новых» и указателей хранения в vector<IFunnyInterface*>
Поскольку для изменения размера вектора вам нужно использовать конструктор по умолчанию и размер класса, который, в свою очередь, требует, чтобы он был конкретным.
Вы можете использовать указатель, как и другие.
Традиционная альтернатива - использовать vector
указателей, как уже отмечалось.
Для тех, кто ценит, Boost
поставляется с очень интересной библиотекой: Pointer Containers
, которая отлично подходит для задание и освобождает вас от различных проблем, связанных с указателями:
Обратите внимание, что это значительно лучше, чем vector
интеллектуальных указателей, как с точки зрения производительности, так и интерфейса.
Теперь существует 3-я альтернатива, которая заключается в изменении вашей иерархии. Для лучшей изоляции пользователя я несколько раз использовал следующий шаблон:
class IClass;
class MyClass
{
public:
typedef enum { Var1, Var2 } Type;
explicit MyClass(Type type);
int foo();
int bar();
private:
IClass* m_impl;
};
struct IClass
{
virtual ~IClass();
virtual int foo();
virtual int bar();
};
class MyClass1: public IClass { .. };
class MyClass2: public IClass { .. };
Это довольно просто, а вариация Pimpl
идиомы, обогащенная шаблоном Strategy
.
Это работает, конечно, только в том случае, если вы не хотите напрямую манипулировать «истинными» объектами и вовлекаете глубокую копию. Возможно, это не так, как вы пожелаете.
В этом случае мы не сможем использовать даже этот код:
std::vector <IFunnyInterface*> funnyItems;
или
std::vector <std::tr1::shared_ptr<IFunnyInterface> > funnyItems;
Поскольку нет связи ISA между FunnyImpl и IFunnyInterface и существует нет неявного преобразования между FUnnyImpl и IFunnyInterface из-за частного наследования.
Вы должны обновить свой код следующим образом:
class IFunnyInterface
{
public:
virtual void IamFunny() = 0;
};
class FunnyImpl: public IFunnyInterface
{
public:
virtual void IamFunny()
{
cout << "<INSERT JOKE HERE>";
}
};
Вы не можете создать вектор абстрактного типа класса, потому что вы не можете создавать экземпляры абстрактного класса и контейнеры стандартной библиотеки C ++, такие как std :: vector store values (например, экземпляры). Если вы хотите это сделать, вам нужно будет создать вектор указателей на абстрактный тип класса.
Ваш рабочий стол не будет работать, потому что виртуальные функции (вот почему вы хотите, чтобы абстрактный класс был в первую очередь ) работают только при вызове через указатели или ссылки. Вы также не можете создавать векторы ссылок, поэтому это вторая причина, почему вы должны использовать вектор указателей.
Вы должны понимать, что C ++ и C # имеют очень мало общего. Если вы намереваетесь изучать C ++, вы должны думать об этом как о начале с нуля и прочитать хороший посвященный учебник на C ++, такой как Accelerated C ++ от Koenig и Moo.