C ++继承方法但返回类型错误(自动转换?typeid(* this)?)

C++ inheritance of methods but wrong return types (automatic casting? typeid(*this) ?)

我有一个带有返回类对象的方法的基类,还有一个派生类。现在,当我有一个派生类对象并调用在基类中定义的方法时,返回的值是ob类型的baseclass,不幸的是,它不是派生类类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class BaseClass {
public:
  typeof(*this) myMethod1() {return *this;} // nice if that would work
  BaseClass& myMethod2() {return *this;}
  BaseClass myMethod3() {return BaseClass();}
};
class DerivedClass : public BaseClass {};

DerivedClass tmp;
tmp.myMethod1();
tmp.myMethod2();
tmp.myMethod3();
// all three methods should return an object of type DerivedClass,
// but really they return an object of type BaseClass

所以我希望实现的是使用超类的方法,但是使用派生类的返回类型(自动转换?).mymethod1()是我唯一能想到的,但它不起作用。

我搜索过,但没有找到满意的东西。


您希望使用CRTP(http://en.wikipedia.org/wiki/cur奇地使用重复出现的模板模式)模式:

1
2
3
4
5
6
7
8
9
10
11
template <class Derived>
class BaseClass {
public:
  Derived *myMethod1() {return static_cast<Derived *>(this);}
  Derived& myMethod2() {return static_cast<Derived&>(*this);}
};
class DerivedClass : public BaseClass<DerivedClass> {};

DerivedClass tmp;
tmp.myMethod1();
tmp.myMethod2();


只需使用协变返回类型规则就可以了。

重述它:如果您通过指针或引用返回,您的重写可以显式地从基类中返回的类型派生一个返回类型,并且它是一个有效的虚拟重写。

10.3 Virtual functions §7

The return type of an overriding function shall be either identical to the return type of the overridden
function or covariant with the classes of the functions. If a function D::f overrides a function B::f, the
return types of the functions are covariant if they satisfy the following criteria:
— both are pointers to classes, both are lvalue references to classes, or both are rvalue references to
classes112
— the class in the return type of B::f is the same class as the class in the return type of D::f, or is an
unambiguous and accessible direct or indirect base class of the class in the return type of D::f
— both pointers or references have the same cv-qualification and the class type in the return type of D::f
has the same cv-qualification as or less cv-qualification than the class type in the return type of B::f.

如果您实际上不想使它成为虚拟的,您只需定义派生类中的函数并调用基类。

如果您有多个派生类,您可以考虑使用crtp来加快速度:

1
2
3
4
5
6
7
8
9
template <class X>
struct CRTP : BaseClass {
  X& myMethod1() {return static_cast<X&>(*this;)} // covariant maybe-virtual
  X& myMethod2() {return static_cast<X&>(*this;)} // covariant maybe-virtual
  X myMethod3() {return X();} // Not virtual
};
struct DerivedClass1 : CRTP<DerivedClass1> {};
struct DerivedClass2 : CRTP<DerivedClass2> {};
struct DerivedClass3 : CRTP<DerivedClass3> {};


谢谢你的回答。也许我的问题不够清楚,但我可以通过添加另一个构造函数自己解决我的问题。

澄清一下:我有一个带有成员方法运算符+()的基类和派生类(没有该成员方法)。现在,当我调用派生类的"operator+()"时,返回类型是baseclass。我可以简单地将操作符+()添加到派生类中,但是,添加接受超级类型参数的复制构造函数(这里是baseclass)解决了问题,返回类型自动变为正确的:

1
DerivedClass(const BaseClass& src) : BaseClass(src) {}