在派生类中重新定义类型定义
Redefining a typedef in derived class?
所以在搜索了很多问题的答案后,我最终放弃了我的谷歌技能。
我有一个基类 base 和一个派生类 derived 。我想用派生类中的类型覆盖基类中的类型。下面是一个例子:class Apple {
public:
Apple() { }
// ...
};
class Orange {
public:
Orange() { }
// ...
};
class Base {
public:
typedef Apple fruit;
// ...
virtual fruit func() { return Apple(); }
};
class Derived : public Base {
public:
typedef Orange fruit;
// ...
fruit func() override { return Orange(); } // <-- Error C2555!
};
这段代码不起作用,它给出了
C2555 error ('Derived::func': overriding virtual function return type differs and is not covariant from 'Base::func').
以上是我尝试过的解决方案之一。我还尝试在基中创建一个虚拟嵌套类,并在派生中重新定义,这也没有编译(它也非常混乱)。
我也不能从相同的基类派生出apple和Oranges来返回指向它们在 base 和Derived中的父类的指针/引用。我需要物理地返回对象的实例。
- 是否有任何方法可以声明抽象类型?
- 如果没有,是否有其他解决方案可以达到我的目的想做什么?
首先,看看下面的语法:
fruit func() override { return Orange(); }
override
是什么?在c++ 03中,没有这样的关键字。它只在c++ 11中存在。确保你使用的编译器知道这个关键字。
第二,在派生类中,fruit
确实是Orange
。重新定义typedef不是问题。问题是,Orange
和Apple
不是协变型。从一个推导出另一个会使它们协变。在您的情况下,您必须从Apple
派生Orange
才能使其工作。
注意您必须将返回类型从fruit
更改为fruit*
或fruit&
。
class Orange : public Apple {}; //correct - your code will work
class Apple : public Orange {}; //incorrect - your code will not work
这个想法是,在基类中,返回类型应该是基类类型(即Apple
)的指针/引用,而在派生类中,返回类型可以是Apple
类型的指针/引用或从它派生的任何类。
顺便问一下,这有意义吗?从Apple
推导Orange
?
下面的类设计如何?
class Fruit {};
class Apple : public Fruit {};
class Orange : public Fruit {};
class Base
{
virtual Fruit* f();
};
class Derived : public Base
{
virtual Fruit* f();
};
不需要使用typedef
这从一开始就没有多大意义。Derived
应该能够在任何需要Base
的地方使用,所以您应该能够执行
Base *foo = new Base();
Apple x = foo->func(); // this is fine
Base *bar = new Derived();
Apple y = foo->func(); // oops...
我认为你需要考虑一个不同的设计。这里不清楚您的目标是什么,但我猜您可能希望Base
是一个类模板,Fruit
作为模板参数,或者您可能需要完全摆脱继承。
你不能这样做,如果你有一个值对象,你必须知道它是什么类型。(这是静态类型语言(如c++)与动态类型语言(如Ruby和Python)之间的主要区别之一。)
有很多方法可以解决这个问题。首先,让我们假设Apple
和Oragne
有一个名为Fruit
的公共基类。一种解决方案是使用new
动态分配对象并返回一个Fruit
指针。
另一个解决方案是,你的函数可以不返回一个值,而是接受一个指向Fruit的指针或引用,然后它可以填充这个指针或引用。
另一个解决方案是使用某种容器对象,其内部可以存放Apple或Orange。这样你就可以返回它
报告的错误告诉您所需要的一切。这意味着Derived
方法中返回的类型需要从基方法中返回的类型派生出来。
这样,如果基方法被虚拟调用,返回的对象可以被视为基方法返回的对象。
实际上,你需要返回一个指针或引用来做这件事。
你需要做的是定义一个新的Fruit
基类,并从它派生Apple
和Orange
。
然后让func()
返回一个Fruit*
。
这将给您留下一个问题,即确保Fruit*
在某些时候是delete
'd。
有了更多的上下文,我怀疑(可能是薄)模板是您所追求的解决方案,而不是继承。
- 使用QJsEngine在Qt中注册自定义类型
- 在UE4中使用未定义类型'UTextBlock'
- 修改"std::set"中用户定义类型的值
- 当我使用自定义类型创建动态数组时,即使使用字符串,它似乎也不起作用
- QtQuick - qml:28:错误:未知方法返回类型:自定义类型
- 如何使自定义类型在unordered_map中用作键
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- Qt5 远程对象 + 自定义类型,但不在 POD 中
- 为什么转换函数声明不需要至少一个定义类型说明符
- 标准::原子中的自定义类型
- 如何使用自定义类型声明Arduino数组?
- 如何在 Cython 中定义返回 cpp 定义类型的函数?
- 使用自定义访问者时具有自定义类型的提升变体失败(源自 boost::static_visitor)
- 您可以将binary_search应用于具有自定义类型的矢量吗?
- 在自定义类型图中重用 SWIG 映射
- 扩展自定义类型的spdlog
- vim使用户定义类型的COLOR与C++中的基本类型相同
- 重载自定义类型的 std::to_string 和 std::to_chars?
- 具有未声明/未定义类型的 typedef 结构
- 函数重载:内置类型与用户定义类型