Можем ли мы найти вызывающую функцию в функции-члене в C ++? - PullRequest
1 голос
/ 19 декабря 2011

У меня есть класс, и давайте назовем его классом myClass

class myClass{

  // some math operations
  myClass get_difference(myClass &b)
  {
       print_operation(*this, b);
       do_something else
       return...
  }
  myClass get_sum(myClass &b)

// pseudocode 
void print_operation(const myClass *a, const myClass &b)
{
     if function == get_sum
         print a << "plus" << b;
     if function == get_difference
         print a << "minus" << b;
}

  // overload cout as well
};

Предположим, я вызвал следующее

myClass anObject(1,2);
myClass anotherObject(3,4);

anObject.get_sum(anotherObject);
anObject.get_difference(anotherObject);

get_sum / get_difference вызовет print_operation ,но я хочу, чтобы можно было определить вызывающего абонента, чтобы использовать другой выходной формат.

Наивный подход: использовать switch-case Добавить новый параметр с именем "id".Присвойте каждой функции (вызывающей стороне) идентификатор и используйте операторы switch-case в print_operation.

Однако есть ли альтернатива?Более элегантное решение?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 19 декабря 2011

Рассматривали ли вы добавление virtual const std::string& getFormatted() const в вызывающую сторону?

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

Если формат является функцией только длины печати каждого аргумента (намного проще), вы можете использовать virtual size_t getFormatLength() const.

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

Это ООП / полиморфизм на работе.

Как ответил Эндрю Маршалл в своем комментарии выше, часть ООП / инкапсуляции заключается в том, что вы не должны ничего знать о реализации вызывающей стороны.

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

class myClass
{
  public:
    virtual std::string getFormatted( const std::string& op ) const = 0;
};

class A : public myClass
{
  public:
    virtual std::string getFormatted( const std::string& op ) const
    {
      // switch on the value of op or the length of op, etc...

      return std::string( "this, formatted according to class A specs and op" );
    }
};

class B : public myClass
{
  public:
    virtual std::string getFormatted( const std::string& op ) const
    {
      // switch on the value of op or the length of op, etc...

      return std::string( "this, formatted according to class B specs and op" );
    }
};

void print_operation(const myClass &a, const myClass &b )
{
  std::string op;

  if ( function == get_sum ) {
    op = "plus";
  } else if ( function == get_difference ) {
    op = "minus"; 
  }
  std::cout << a.getFormatted( op ) << op << b.getFormatted( op );
}
2 голосов
/ 19 декабря 2011

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

Так что ответ не является более элегантным решением.

1 голос
/ 19 декабря 2011

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

Извлекая урок из .NET, вы можете рассмотреть проект, в котором у вас есть строка форматаопределить способ вывода данных, например, в IFormattable.ToString.В этом примере строка формата используется для различения различных форматов вывода.В вашем случае вы можете определить его с помощью целого числа, перечисления или чего-либо подходящего.

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