Хранить объекты абстрактного типа

0

Предположим, что у меня есть абстрактный класс/интерфейс:

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 - это конкретный класс, что-нибудь изменится?

  • 2
    Я не понимаю Вы хотите иметь вектор, который может хранить объекты MyInterface , но не хотите делать vector<MyInterface*> ?
  • 0
    Там нет разницы в хранении, будь то абстрактное или конкретное
Показать ещё 4 комментария
Теги:

3 ответа

2
Лучший ответ

Там просто улучшение, но в основном это одно и то же: вы можете хранить unique_ptr вместо сырых указателей.

Но концептуально вам придется использовать указатели, так как это единственный способ борьбы с полиморфизмом в этом случае.

затем

Я хочу иметь вектор, который может хранить объекты MyInterface, которые я намерен хранить в объектах класса MyImplemented.

Если вы знаете, что будете хранить только объекты типа MyImplemented, вы также можете просто напрямую использовать std::vector<MyImplemented>.

  • 0
    Полиморфизм не требует указателей. Не нарезка требует указателей.
  • 0
    @LightnessRacesinOrbit Я знаю, что полиморфизм также может быть сделан со ссылками, хотя я полагаю, что std::vector<MyInterface&> будет весьма неудобным в этом случае. Вы подразумевали что-то еще с "Полиморфизм не требует указателей"? (Возможно, я что-то пропустил тогда).
Показать ещё 5 комментариев
3

Вы можете использовать интеллектуальный указатель вместо встроенного указателя (std :: unique_ptr), или вы можете использовать boost :: any, а затем применить к реальному типу

  • 0
    Что ж, поправьте меня, если я ошибаюсь, но я думаю, что вы должны уточнить, что boost::any будет менее гибким, чем указатели, так как вы должны знать базовый тип перед выполнением boost::any_cast , таким образом устраняя возможность использования объекты хранятся в векторе через абстрактный интерфейс.
  • 0
    JBL: Вы правы - поддержка :: любой не лучший выбор для этого случая
0

Если у вас будет только MyImplemented, тогда нет причин, по которым вы не можете сделать

std :: вектор myVector;

Распределение памяти проще с этим макетом, и вы можете получить некоторые повышения производительности, так как макет памяти (может быть) более дружественный к кешу.

Это (однако) подразумевает взаимно-однозначную взаимосвязь между интерфейсом и реализацией. В этом случае очень мало нужно использовать полиморфизм: он делает ваш код более сложным. Вы также получаете (небольшой) удар производительности с помощью вызовов виртуальных функций.

Что НЕ будет работать:

std :: вектор myVector;//SO BAD

Из-за сужения: вам нужно использовать ссылки какого-то типа.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню