【发布时间】:2017-08-25 15:28:20
【问题描述】:
当我在学习 C++ 中的方法覆盖规则时,我一直在阅读协变类型,它基本上似乎是子类或派生类的一个花哨的词(至少就 C++ 而言)。我做了一些测试,发现有一个我不理解的令人惊讶的异常。如下所示:
struct Animal {};
struct Cat : Animal{};
Cat gCat;
Animal* getAnimalPointer() { return &gCat; } // Returning covariant type by pointer, OK
Animal& getAnimalReference() { return gCat; } // Returning covariant type reference, OK
Animal getAnimalCopy() { return gCat; } // Returning covariant type by copy, OK
// All good
// Now testing virtual method overriding by using C++ feature of
// allowing overriding virtual methods using covariant return types
struct AnimalShelter
{
virtual Animal* getAnimalPointer() {};
virtual Animal& getAnimalReference() {};
virtual Animal getAnimalCopy() {}
};
struct CatShelter : AnimalShelter
{
Cat* getAnimalPointer() override; // Returning covariant type by pointer, OK
Cat& getAnimalReference() override; // Returning covariant type by reference, OK
Cat getAnimalCopy() override; // Returning covariant type by copy, fail
/* Visual Studio error: return type is not identical to nor covariant with
return type "Animal" of overriden virtual function CatShelter::getAnimalCopy*/
};
编辑:事实证明,只有在虚拟情况下,C++ 才会阻止您通过复制返回协变类型,请参阅 Fire Lancer 的出色回答,了解可能的原因。还有另一个与此类似的问题,在 cmets 中有一个有趣的讨论,关于这样做的原因是否是调用者不知道在虚拟调用的情况下为返回类型分配多少空间。
overriding virtual function return type differs and is not covariant
【问题讨论】:
-
您使用
Animal getAnimalCopy() { return Cat(); }进行对象切片。 -
是的,我认为那样会不那么混乱。
-
“但是从函数返回时似乎没问题” C++ 的问题在于,并非所有看起来都很好的东西实际上都很好;)
-
似乎从函数、指针、引用和副本返回时,您可以返回协变类型,但是通过覆盖虚方法,您只能返回指针和引用。奇怪。
标签: c++ inheritance overriding virtual