简体   繁体   中英

C++14 ignore return type in interface getter but specify it in implementation

I have three classes of objects:

  • class Foo: has a mesh, and I need to get that mesh;
  • class Bar: is a Foo, but has some further capabilities which Foo doesn't have;
  • class Baz: is a Foo, but has another completely independent set of capabilities which neither Foo nor Bar have.

All three classes need to have a way to give me their mesh which, however, can be implemented in many ways, of which I need (at the moment I can't see another way) to use at least 2 different ones, which are MeshTypeA and MeshTypeB.

I would like to have a common interface for different implementations of the same concept (getMesh), however, I can't use auto in a virtual method. I'm lacking the facility to make the code have sense. I would like to have:

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 and MeshTypeB are not exclusive to Foo, Bar, or Baz, which is to say all three could have both types of mesh. However I really don't care for which MeshType I get when I later use it.

Do I need to wrap MeshTypeA and MeshTypeB in my own MeshType? Is it a matter of templating the MeshType? I believe there is a way, however related questions aren't helping or I can't formulate my question in a meaningful enough way.

I have also found this where the author uses a Builder class and decltype, but I don't have such a class. Maybe that would be it? Do I need a MeshLoader sort of class as an indirection level?

If your MeshTypes all have a common (abstract) base class, then you can just return (a pointer or reference to) that in the virtual function defintions, and the derived classes can then return their concrete mesh types, and all will be well. If you have code that can work on any mesh type, it is going to need that abstract base anyways.

If your MeshTypes do not all have a common base class, why even have a getMesh method in Foo at all? Remove it and give each of the concrete classes it's own getMesh method that doesn't override (and has nothing in particular to do with the meshes in any other concrete class).

A function's return type is part of its interface. You can't just change it willy-nilly. More specifically, you cannot have a base class virtual method return one thing while an overridden version returns another. OK, you can , but only if the derived version's return type is convertible to the base class return type (in which case, calling through the base class function will perform said conversion on the overriding method's return type).

C++ is a statically typed language; the compiler must know what an expression evaluates to at compile time. Since polymorphic inheritance is a runtime property (that is, the compiler is not guaranteed to be able to know which override will be called through a base class pointer/reference), you cannot have polymorphic inheritance change compile-time constructs, like the type of a function call expression. If you call a virtual method of a base class instance, the compiler will expect this expression to evaluate to what that base class's method returns.

Remember: the point of polymorphic inheritance is that you can write code that doesn't know about the derived classes and have it still work with them. What you're trying to do violates that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM