Предположим, что у меня есть абстрактный класс/интерфейс:
class MyInterface {
public:
virtual void foo() = 0;
virtual ~MyInterface(){}
};
class MyImplemented : public MyInterface {
public:
virtual void foo(){ /*do something*/ };
}
и я хочу иметь вектор, который может хранить объекты MyInterface
, которые я намерен хранить в объектах класса MyImplemented
.
Есть ли другой способ сделать это иначе, чем сделать вектор указателей на объекты MyInterface
? т.е.
std::vector<MyInterface*> myVector;
Кроме того, если MyInterface
- это конкретный класс, что-нибудь изменится?
Там просто улучшение, но в основном это одно и то же: вы можете хранить unique_ptr
вместо сырых указателей.
Но концептуально вам придется использовать указатели, так как это единственный способ борьбы с полиморфизмом в этом случае.
затем
Я хочу иметь вектор, который может хранить объекты MyInterface, которые я намерен хранить в объектах класса MyImplemented.
Если вы знаете, что будете хранить только объекты типа MyImplemented
, вы также можете просто напрямую использовать std::vector<MyImplemented>
.
std::vector<MyInterface&>
будет весьма неудобным в этом случае. Вы подразумевали что-то еще с "Полиморфизм не требует указателей"? (Возможно, я что-то пропустил тогда).
Вы можете использовать интеллектуальный указатель вместо встроенного указателя (std :: unique_ptr), или вы можете использовать boost :: any, а затем применить к реальному типу
boost::any
будет менее гибким, чем указатели, так как вы должны знать базовый тип перед выполнением boost::any_cast
, таким образом устраняя возможность использования объекты хранятся в векторе через абстрактный интерфейс.
Если у вас будет только MyImplemented, тогда нет причин, по которым вы не можете сделать
std :: вектор myVector;
Распределение памяти проще с этим макетом, и вы можете получить некоторые повышения производительности, так как макет памяти (может быть) более дружественный к кешу.
Это (однако) подразумевает взаимно-однозначную взаимосвязь между интерфейсом и реализацией. В этом случае очень мало нужно использовать полиморфизм: он делает ваш код более сложным. Вы также получаете (небольшой) удар производительности с помощью вызовов виртуальных функций.
Что НЕ будет работать:
std :: вектор myVector;//SO BAD
Из-за сужения: вам нужно использовать ссылки какого-то типа.
MyInterface
, но не хотите делатьvector<MyInterface*>
?