C ++ 14 игнорирует возвращаемый тип в интерфейсе getter, но указывает его в реализации - PullRequest
0 голосов
/ 19 ноября 2018

У меня есть три класса объектов:

  • класс Foo: есть сетка, и мне нужно получить эту сетку;
  • класс Bar: это Foo, но имеет некоторыедругие возможности, которых нет у Foo;
  • class Baz: это Foo, но есть еще один совершенно независимый набор возможностей, которых нет ни у Foo, ни у Bar.

Все три класса нужнычтобы у меня был способ дать мне свою сетку, которая, однако, может быть реализована многими способами, из которых мне нужно (на данный момент я не вижу другого пути) использовать как минимум 2 разных, которые являются MeshTypeA и MeshTypeB.

Я хотел бы иметь общий интерфейс для разных реализаций одной и той же концепции (getMesh), однако я не могу использовать auto в виртуальном методе.Мне не хватает средств, чтобы код имел смысл.Я хотел бы иметь:

class Foo
{
public:
  virtual ~Foo() = 0;
  virtual auto getMesh() const = 0;  // doesn't compile
};

class Bar : public Foo
{
public:
  virtual ~Bar() = 0;
  virtual auto getMesh() const = 0;  // doesn't compile
  // other virtual methods
};

class ConcreteFooWhichUsesA : public Foo
{
public:
  ConcreteFooWhichUsesA();
  ~ConcreteFooWhichUsesA();
  auto getMesh() const override {return mesh_;};

private:
  MeshTypeA mesh_;
};

class ConcreteBarWhichUsesB : public Bar
{
public:
  ConcreteBarWhichUsesB();
  ~ConcreteBarWhichUsesB();
  auto getMesh() const override {return mesh_;};
  // other implementations of virtual methods

private:
  MeshTypeB mesh_;
};

MeshTypeA и MeshTypeB не являются эксклюзивными для Foo, Bar или Baz, то есть все три могут иметь оба типа меша.Однако мне действительно все равно, какой MeshType я получу при последующем его использовании.

Нужно ли мне оборачивать MeshTypeA и MeshTypeB в свой собственный MeshType?Это вопрос шаблона MeshType?Я считаю, что есть способ, однако связанные вопросы не помогают, или я не могу сформулировать свой вопрос достаточно осмысленно.

Я также нашел это , где автор используетКласс Builder и decltype, но у меня нет такого класса.Может быть, так и будет?Нужен ли класс MeshLoader в качестве уровня косвенности?

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

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

Если ваши MeshTypes не имеют общего базового класса, почему вообще есть метод getMesh в Foo? Удалите его и передайте каждому из конкретных классов собственный метод getMesh, который не переопределяет (и не имеет ничего общего с сетками в любом другом конкретном классе).

0 голосов
/ 19 ноября 2018

Тип возвращаемого значения функции является частью ее интерфейса.Вы не можете просто изменить это волей-неволей.Более конкретно, вы не можете заставить виртуальный метод базового класса возвращать одно, а переопределенная версия - другое.ОК, вы можете , но только если возвращаемый тип производной версии может быть преобразован в возвращаемый тип базового класса (в этом случае вызов через функцию базового класса будет выполнять указанное преобразование для возвращаемого типа переопределяющего метода).

C ++ - статически типизированный язык;компилятор должен знать, что вычисляет выражение во время компиляции.Поскольку полиморфное наследование является свойством времени выполнения (то есть компилятору не гарантируется, что он сможет знать, какое переопределение будет вызываться через указатель / ссылку базового класса), вы не можете иметь полиморфные конструкции изменения времени наследования, такие как типвыражение вызова функции.Если вы вызываете виртуальный метод экземпляра базового класса, компилятор будет ожидать, что это выражение оценивает то, что возвращает метод этого базового класса.

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

...