Что делать с неиспользуемым методом в наследуемом классе?

371
20 января 2018, 01:15

Есть базовый абстрактный класс с некоторыми методами.

Эти методы используют большинство производных классов.

Но для одного типа класса функция не нужна.

Например:

const MyStruct& childClass::getMyStruct()
{
    return что?
}

У childClass не может быть члена MyStruct, чтобы его вернуть.

Всё-таки как сделать правильно? Сунуть объект, чтобы был, или есть нормальное решение?

Answer 1

Измените иерархию. Абстрактный класс БЕЗ этого метода, его наследник - абстрактный класс С ним. И соответствующие наследники - от основного абстрактного класса - тот ваш производный, для которого реализация невозможна; все остальные - производные от производного абстрактного.

Answer 2

Если в базовом классе определены абстрактные методы, то возможны два варианта

  1. Эти методы описывают некий интерфейс работы с этим классом. Тогда эти методы должны иметь уровень видимости public и будут вызываться снаружи класса. Тогда наследник понятия не имеет какие методы будут вызываться
  2. Эти методы вызываются из других методов этого класса. Тогда наследник просто обязан их переопределить для обеспечения работоспособности базового класса

В любом случае наследник не имеет никакого права говорить, что какие-то методы не нужны. Если наследник не может реализовать тот или иной метод, то сам наследник должен быть абстрактным.

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

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

class Base {
  virtual bool compare() = 0;
  virtual const MyStruct& getMyStruct() = 0;
  virtual const MyStruct& getMyOtherStruct() = 0;
  void doSomething() {
    MyStruct = struct1;
    if (compare())
      getMyStruct() = struct1;
    else
      getMyOtherStruct() = struct1;
  }
}

тогда если мы определим в дочернем классе

class Child:public Base {
  bool compare() {
    return true;
  }
}

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

const MyStruct& getMyOtherStruct() {
  throw "Call abstract method";
}

Но нужно помнить об одной особенности. Никто не мешает сделать так

class Child2:public Child {
  bool compare() {
    return false;
  }
}

тогда компилятор уже не сможет предупредить, что не все методы определены и если забыть самому переопределить getMyOtherStruct то получите законный exception

Answer 3

Если, несмотря на возможные архитектурные изъяны с наследованием, функция всё таки нужна, можно предложить заменить ссылку хотя бы на указатель. И возвращать в таком случае nullptr. Хотя, как я считаю, наличие функции в базовом классе должно подразумевать ее существование во ВСЕХ производных классах. Иначе, стоит задуматься о создании более расширенной иерархии классов.

Answer 4
const MyStruct& childClass::getMyStruct();

Попробуй.

throw;
return *(MyStruct*)(nullptr);

Но толку в ретурне этом 0.

READ ALSO
qmake и несколько целей

qmake и несколько целей

здравствуйте, есть проект такой структуры: хочу чтоб при сборке qmake mainpro && make собирались подпроекты сервера и клиента:

251
С++ UDP Win -> Linux

С++ UDP Win -> Linux

Я написал 2 простых класса udp(путём нарезания какого-то кода сервера и клиента)

334
Google testing: как обработать исключения из SetUp() / TearDown()? - C++

Google testing: как обработать исключения из SetUp() / TearDown()? - C++

Например я хочу проверить умный указательИ убедится что локальный объект уничтожается при выходе из своего поля видимости:

279