Необязательные аргументы метода в C ++, но со стороны вызываемого? - PullRequest
1 голос
/ 28 октября 2010

В C ++ методы могут иметь необязательные аргументы, например:

void myFunction (int arg1, int arg2=0);

В этом случае myFunction может вызываться с 1 целым или двумя.Если вы опустите второе целое число, вместо него будет передано значение 0.

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

class IObserver
   {
   public:
      virtual bool operator() (OtherClass *instance) = 0;
   };

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

class IObserver
   {
   public:
      virtual bool operator() (OtherClass *instance, int firstOptional, int secondOptional) = 0;
   };

Но, учитывая, что эти новые аргументы имеют смысл только для небольшого числа очень специфических наблюдателей, яне хочу добавлять дополнительные аргументы к остальным 99% наблюдателей.

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

addObserver (observee, [](OtherClass *instance)->bool {/*do something here*/ return true;}

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

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

Какие-либо предложения о том, как решить это простым, но простым способом?

Ответы [ 4 ]

3 голосов
/ 28 октября 2010

Если вы не хотите реализовывать перегрузки operator bool в каждом конкретном классе, который реализует интерфейс, то вы можете просто позволить интерфейсу предоставлять не виртуальные перегрузки, которые перенаправляют вызовы в одну виртуальную функцию-член (с Однако много аргументов), которые должны быть реализованы.

Да, это немного отличается от интерфейсов Java, которые не могут обеспечить такую ​​функциональность.

Еще один хороший способ: если вы хотите, вы можете разрешить не виртуальным серверам пересылки выполнять проверку до и после условия и / или проверку аргументов, а также устанавливать точки останова для отладки. : -)

Приветствия & hth.,

1 голос
/ 28 октября 2010

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

class IObserver 
   { 
   public: 
      virtual bool operator() (OtherClass *instance, IObserverArgs* args) = 0;
   }; 

А для реализации, требующей дополнительных аргументов, может быть собственная реализация IObserverArgs.Однако это может быть недостаточно гибким по отношению к лямбде.

1 голос
/ 28 октября 2010

Но вы можете перегрузить operator() на количество и типы аргументов. Почему это не удовлетворительно?

0 голосов
/ 28 октября 2010

Вы можете рассматривать версию operator() с дополнительными аргументами просто как другую функциональность вашего конкретного класса.

Перегрузите operator() в нескольких конкретных классах, которым требуется дополнительный аргумент.

class Observer1
{
public:
   virtual bool operator() (OtherClass *instance);
   bool operator() (OtherClass *instance, int firstOptional, int secondOptional);
};
...