Функции-члены C ++, объединяющие типы возвращаемых данных и производные классы

В этом надуманном примере:

struct point_2d {
  point_2d& x( int n ) {
    x_ = n;
    return *this;
  }

  point_2d& y( int n ) {
    y_ = n;
    return *this;
  }

  int x_, y_;
};

struct point_3d : point_2d {
  point_3d& z( int n ) {
    z_ = n;
    return *this;
  }

  int z_;
};

int main() {
  point_3d p;
  p.x(0).y(0).z(0); // error: "point_2d" has no member named "z"
  return 0;
}

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

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

Есть ли какие-нибудь умные способы решить эту проблему и по-прежнему поддерживать возможность связывания функций-членов?


Фактическая проблема

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

class base_exception : public std::exception {
  // ...
  base_exception& set_something( int some_param ) {
    // ...
    return *this;
  }
};

class derived_exception : public base_exception {
  // ...
};

int main() {
  try {
    // ...
    if ( disaster )
      throw derived_exception( required_arg1, required_arg2 )
            .set_something( optional_param );
  }
  catch ( derived_exception const &e ) {
    // terminate called after throwing an instance of 'base_exception'
  }
}

Проблема в том, что set_something () возвращает base_exception , но catch ожидает производное_исключение . Конечно, человек может сказать, что фактическим типом исключения является производное_исключение , но компилятор явно не может сказать.

Это проблема, которую я действительно пытаюсь решить , т.е. как сделать так, чтобы базовый класс исключения мог устанавливать необязательные параметры для объекта исключения, но при этом возвращал экземпляр производного типа. Пример point_2d , который я привел выше, является (я считаю) уменьшенной и более простой версией той же проблемы, которую люди могут понять, и что решение меньшей проблемы также решит мою настоящую проблему.

Обратите внимание, что Я действительно думал о том, чтобы сделать base_exception шаблоном и передать производный тип, например:

template<class Derived>
class base_exception {
  // ...
  Derived& set_something( int some_param ) {
    // ...
    return *this;
  }
};

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

9
задан Paul J. Lucas 16 February 2011 в 07:28
поделиться