Переопределение того же метода только в некоторых дочерних классах, как избежать дублирования? - PullRequest
1 голос
/ 20 июня 2009

Я использую базовый класс, и в настоящее время для него есть 5 дочерних классов. Некоторые функции схожи для 3 детей, но не для всех. Я не могу представить новый уровень иерархии, так как некоторые методы повторяются в дочернем элементе 1,2,3, а некоторые в 2,3,4.

Как лучше всего избежать переопределения методов у всех трех детей и повторения кода.

Ответы [ 8 ]

3 голосов
/ 20 июня 2009

Если вы не хотите использовать множественное наследование, вы также можете использовать состав .

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

1 голос
/ 20 июня 2009

Или вы можете исследовать Шаблон стратегии . Иногда отношение HAS-A является лучшим выбором, чем IS-A. Конечно, я не знаю, позволяет ли ваша проблема ввести шаблон

1 голос
/ 20 июня 2009

Вы можете добавить новый промежуточный класс с protected методами для различных реализаций каждой функции.Затем в дочерних классах переопределите методы из исходного базового класса и вызовите соответствующие protected методы из этого нового промежуточного класса.

1 голос
/ 20 июня 2009

Создайте смешанный класс, и наследуйте от него и дети с общим методом. Например:

class Base {
  public:
    virtual commonFunction() { /* default implementation */ };
}; 

class Mixin {
  public:
     virtual notSoCommonFunction() { /* default implementation */ };
};

class D1 : public Base {
  public:
     virtual commonFunction() { /* override implementation */ };
};

class D2 : public Base, public Mixin {
  public:
     virtual commonFunction() { /* override implementation */ };
     virtual notSoCommonFunction() { /* override implementation */ };
};

class D3 : public Base, public Mixin {
  public:
     virtual commonFunction() { /* override implementation */ };
     virtual notSoCommonFunction() { /* override implementation */ };
};

Таким образом, все классы D1, D2, D3 реализуют (и необязательно переопределяют) commonFunction, но реализуют только D2 и D3 (и при необходимости переопределяют notSoCommonFunction).

0 голосов
/ 13 июля 2009

Другое решение, которое могло бы работать, следующее:

Предположим, что базовый класс называется MyBaseClass, дочерние классы - от ChildClass1 до ChildClass5, а функция, которую вы хотите дублировать, выглядит следующим образом:

public int foo(Object args)
{...}

Теперь вы можете создать отдельный класс (назовите его «HelperFunctions» или что-то в этом роде) с помощью статического метода:

public static int fooHelper(BaseClass theClass, Object args)
{insert duplicated code here}

и затем используйте функции foo в классах, которые вы хотите вызвать этой вспомогательной функцией.

Это имеет несколько преимуществ:

  1. Вы не создаете новые объекты и не меняете иерархию типов. Поскольку вспомогательная функция является статической, вы можете вызывать ее, не добавляя новых объектов.
  2. Вы по-прежнему можете вызывать методы класса, потому что вы передаете объект типа BaseClass, поэтому вы можете вызывать методы для него так же, как и внутри класса.

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

Я не уверен, что понимаю, в чем проблема. По крайней мере, в моем решении вы передаете объект, так что вы можете вызывать любые методы и обращаться к переменным экземпляра для объекта, который вы хотите. Проблема в том, что переменные экземпляра или методы, к которым вы хотите получить доступ, являются закрытыми, поэтому вы не можете получить к ним доступ вне класса? В этом случае вы можете легко решить эту проблему, объявив вспомогательную функцию дружественной функцией (просто ознакомьтесь с руководствами по использованию функции "c ++ friend" в Google)

0 голосов
/ 24 июня 2009

Проверка кода может подождать, прежде чем вы получите удовлетворительный ответ для этого, верно? Здорово. : -)

0 голосов
/ 20 июня 2009

Если вам нужен доступ к другим членам класса, вы можете использовать шаблонные миксины, которые static_cast this указывают на соответствующий тип:

template<class T>
class M1Mixin {
public:
   int m1() {
     return static_cast<T*>(this)->some_value;
   }
};


class Base {
public:
  int some_value;
  ...
};

class A : public Base, M1Mixin<A> {
  ...
};

Это не красиво, но работает.

0 голосов
/ 20 июня 2009

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

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