C++ C++;14忽略接口getter中的返回类型,但在实现中指定它

C++ C++;14忽略接口getter中的返回类型,但在实现中指定它,c++,c++14,virtual,return-type,C++,C++14,Virtual,Return Type,我有三类对象: Foo班:有一个网格,我需要得到那个网格 类栏:是一个Foo,但是有一些Foo没有的进一步的功能 类Baz:是一个Foo,但是有另一组Foo和Bar都没有的完全独立的功能 所有三个类都需要有一种方法来给我它们的网格,但是,可以用很多方法来实现,其中我需要(目前我看不到另一种方法)使用至少两种不同的方法,即MeshTypeA和MeshTypeB 我希望为同一概念的不同实现提供一个通用接口(getMesh),但是,我不能在虚拟方法中使用auto。我缺乏使代码有意义的工具。我希望:

我有三类对象:

  • Foo班:有一个网格,我需要得到那个网格
  • 类栏:是一个Foo,但是有一些Foo没有的进一步的功能
  • 类Baz:是一个Foo,但是有另一组Foo和Bar都没有的完全独立的功能
所有三个类都需要有一种方法来给我它们的网格,但是,可以用很多方法来实现,其中我需要(目前我看不到另一种方法)使用至少两种不同的方法,即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所独有的,也就是说这三种类型的网格都可以同时具有这两种类型。然而,我真的不在乎我以后使用它时得到的网格类型

我需要在我自己的网格类型中包装网格类型A和网格类型B吗?这是一个模板化网格类型的问题吗?我相信有一种方法,但是相关的问题没有帮助,或者我不能以一种有意义的方式来阐述我的问题


我还发现作者在哪里使用了Builder类和decltype,但我没有这样的类。也许就是这样?我需要一个MeshLoader类作为间接层吗?

函数的返回类型是其接口的一部分。你不能随便改变它。更具体地说,您不能让基类虚拟方法返回一件事,而重写版本返回另一件事。可以,但只有当派生版本的返回类型可转换为基类返回类型时(在这种情况下,通过基类函数调用将对重写方法的返回类型执行上述转换)

C++是一种静态类型语言;编译器必须知道表达式在编译时的计算结果。由于多态继承是一个运行时属性(也就是说,编译器不能保证能够知道将通过基类指针/引用调用哪个重写),因此不能让多态继承更改编译时构造,如函数调用表达式的类型。如果调用基类实例的虚拟方法,编译器将期望该表达式的计算结果与该基类的方法返回的结果一致


请记住:多态继承的要点是,您可以编写不知道派生类的代码,并且仍然可以使用它们。您试图执行的操作违反了这一点。

函数的返回类型是其接口的一部分。你不能随便改变它。更具体地说,您不能让基类虚拟方法返回一件事,而重写版本返回另一件事。可以,但只有当派生版本的返回类型可转换为基类返回类型时(在这种情况下,通过基类函数调用将对重写方法的返回类型执行上述转换)

C++是一种静态类型语言;编译器必须知道表达式在编译时的计算结果。由于多态继承是一个运行时属性(也就是说,编译器不能保证能够知道将通过基类指针/引用调用哪个重写),因此不能让多态继承更改编译时构造,如函数调用表达式的类型。如果调用基类实例的虚拟方法,编译器将期望该表达式的计算结果与该基类的方法返回的结果一致


请记住:多态继承的要点是,您可以编写不知道派生类的代码,并且仍然可以使用它们。您试图执行的操作违反了这一点。

如果您的网格类型都有一个公共(抽象)基类,那么您可以在虚拟函数定义中返回(指针或引用),然后派生类可以返回其具体的网格类型,一切都会很好。如果您有可以处理任何网格类型的代码,那么无论如何它都需要抽象基


如果您的网格类型并不都有一个公共基类,那么为什么还要在Foo中使用getMesh方法呢?删除它并为每个具体类提供它自己的getMesh方法,该方法不重写(并且与任何其他具体类中的网格无关)。

如果您的网格类型都有一个公共(抽象)基类,那么您可以在虚拟函数定义中返回(指针或引用),然后,派生类可以返回它们的具体网格类型,一切都会很好。如果您有可以处理任何网格类型的代码,那么无论如何它都需要抽象基


如果您的网格类型并不都有一个公共基类,那么为什么还要在Foo中使用getMesh方法呢?删除它,并为每个具体类提供它自己的getMesh方法,该方法不会重写(并且与任何其他具体类中的网格无关)。

这对我来说似乎已经很清楚了,这就是为什么我在注释中使用了“未编译”,也许我应该更明确地使用“当然它不编译”。我想这个问题,使用
时,编译器必须知道表达式在编译时的计算结果,因为它已经知道了:一旦我进入ConcreteFooWhichUsesA或ConcreteBarWhichusB的实现,实现本身就指定了我使用的网格类型。@LaboratorioBotica:
Foo
的用户不知道是哪个网格类型
MeshType
您正在使用的。考虑<代码>无效FUNC(Foo&F){AutoToe= f GETMESH();}。
事物的类型是什么?在C++中,必须有一个答案,对于所有的用户,代码应该是相同的。因此,这个答案