2014-10-07 4 views
1

Я не делал много полиморфизма в C++, и это было давно, так как я сделал это на других языках, поэтому мне хотелось бы внести свой вклад в то, что я пытаюсь добиться даже возможно.C++ Array/Список различных классов

У меня есть класс «Entity» и несколько других «специализированных» подклассов, которые наследуют Entity. Эти подклассы имеют совершенно разные методы (не переопределение/повторение одного и того же), поскольку они должны выполнять разные функции.

Я ищу способ организовать все эти «сущности» в один список. Если бы я должен был создать единый массив типа «Entity» и назначить подкласс для массива, я бы больше не мог вызывать какие-либо функции подкласса, а только родительские функции «Entity».

Единственный беспорядочный способ, о котором я могу сразу подумать, - создать массив для каждого подкласса, который не кажется таким же аккуратным, когда я думаю о количестве подклассов, которые я намереваюсь сделать, а не укажите объем памяти, который приложение должно будет выделить.

Есть ли какой-либо способ для чистого достижения чего-то похожего на то, что я пытаюсь сделать?

+1

Если у вас есть список экземпляров 'std :: unique_ptr' списка, вы можете сохранить в списке любой выделенный под кучей подкласс' Entity'. При повторении списка вы можете использовать 'dynamic_cast' для фильтрации для интересующих вас объектов в данный момент. – cdhowie

ответ

1

Создайте свой объект любых производных классов, которые вы хотите, а затем сохраните там адреса в массиве указателей Entity.

Используйте оператор dynamic_cast или static_cast, чтобы свести указатели в массиве к соответствующему производному классу и использовать этот литой указатель для вызова методов производного класса.

+0

Умные указатели, надеюсь? – cdhowie

+0

Вы могли бы предоставить крошечный пример этого? – Yattabyte

+0

@cdhowie, да или виртуальные деструкторы. – ThomasMcLeod

2

Если ваши подклассы Entity действительно делают совершенно разные вещи, то, возможно, стоит снова взглянуть на ваш дизайн.

Лучший способ решить эту проблему было бы добавить (возможно, чистый) виртуальный метод на Entity базового класса, что-то вроде

struct Entity 
{ 
    virtual void do_stuff() = 0; 
    virtual ~Entity() {} 
}; 

struct En1 : public Entity 
{ 
    // En1-specific methods 
    void method1(); 
    void method2(); 

    // Override 
    void do_stuff() override { 
     method1(); 
     method2(); 
    } 
}; 

Вы можете создать массив, содержащий указатели на Entity с, т.е.

std::vector<std::unique_ptr<Entity>> vec; 
vec.emplace_back(new En1); 
vec.emplace_back(new En2); 
for (auto&& e : vec) { 
    e->do_stuff(); 
} 

альтернативой было бы попытаться использовать dynamic_cast или typeid работать, какой подкласс вы имеете дело с во время выполнения, но это хрупкая и трудно расширяться в будущем в d конечно не рекомендуется.

Смежные вопросы