C ++, наследование против полиморфизма - PullRequest
4 голосов
/ 13 января 2012

У меня есть немного "философский" вопрос.Существует класс A

class A
{

}

и классы A1, A2, A3, производные от A.

class A1 : public A
{
}

class A2 : public A
{
}

class A3 : public A
{
}

и один статический метод обработки объектов A - A3.Какой вариант должен быть предпочтительным?

A)
class Algorithms  
{
  //Object of derived class could be use instead of the object base class
  public: void test (const A *a) {}
};

или

B)
class Algorithms
{
  public: 
  //Templatize parameter
  template <typename TType>
  void (const TType *a) {}
};

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

Опция b) означает, что входные данные могут быть любого типа, которые не имеют никакого отношения наследования к классу A.

Это будет использоваться в случае, когда метод test () можетработать с другим типом B

class B
{
}

и типами A-A3.

Эти выводы правильны или нет?

Ответы [ 4 ]

3 голосов
/ 13 января 2012

Вы правы.

Чтобы в полной мере воспользоваться полиморфизмом и исключить избыточный код, следует предпочесть вариант А.Используйте опцию B, если вы хотите, чтобы ваш метод также был доступен для других классов, хотя даже тогда, вероятно, лучше перегрузить функцию, чем использовать шаблон.

Скажем, у вас есть два указателя A* a и A1* a1,Если вы вызовете ваш метод для a и a1, во время компиляции будут созданы два метода, один из которых принимает параметр A*, а другой - A1*.Это бесполезно, поскольку полиморфизм может обрабатывать только передачу параметра A*.

Кроме того, существует преимущество, заключающееся в том, что вы можете отделить реализацию от объявления, что невозможно в случае шаблонов.

1 голос
/ 13 января 2012

Шаблон позволяет вам делать то же самое с несвязанными классами.

Вы также можете использовать адаптеры, чтобы вы могли создавать адаптеры для A и B (не связанные), которые являются производными от общего адаптера и выполняют функциивы хотите.

Основная цель шаблона обычно состоит в том, чтобы применить ту же логику к главным образом несвязанным типам, потому что, например, вы каким-то образом манипулируете коллекциями типов, а алгоритм связан с тем, как вы ими манипулируете.

1 голос
/ 13 января 2012

Вариант а в этом случае кажется более удобным, как вы и сделали.В качестве вашего вывода я бы дал ответ: «метод, обрабатывающий базовый класс, фактически обработает все производные классы, и намерение здесь подходит для этого случая».

0 голосов
/ 13 января 2012

Выбор здесь не является (только) стилистическим: опция A обеспечивает полиморфизм во время выполнения, а опция B обеспечивает полиморфизм во время компиляции.Вы не предоставили нам достаточно информации, чтобы выяснить, какая из них предпочтительна в этом случае.

В общем, мой совет - использовать вариант А, если и только если вы хотите позвонить test с A*.С этим приходит предположение, что A, вероятно, является абстрактным базовым классом (или, по крайней мере, имеет виртуальные функции).В этом случае невозможно даже разумно использовать опцию B, и мы надеемся, что test будет состоять из вызова некоторых виртуальных функций на A* с желаемым эффектом (в отличие от dynamic_cast использования его в грязных целях).

Однако, если вы никогда не собираетесь вызывать test с A*, вариант B, как правило, лучше: вы разрешаете использовать функцию с любым типом, и от вызова меньше затрат времени выполнениявиртуальные функции (которые могут быть незначительными, но тем не менее).Это также дает функции несколько большую свободу: например, она может создать другой TType, если необходимо, что сложнее, если вы передадите ему указатель на абстрактный базовый класс.Наконец, вы можете использовать такие функции, как специализация шаблона и статические утверждения, если вы действительно этого хотите.

В общем, вопрос должен звучать так: «Хочу ли я использовать полиморфизм времени выполнения с этим классом?»;выбор между этими двумя становится очевидным, когда вы решите это.

(Кстати, в случае с шаблоном вы, вероятно, захотите передать TType const&, а не TType const*.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...