C++ 在派生类中重新定义typedef?
所以在搜索了很多问题的答案后,我最终放弃了我的谷歌技能 我有一个基类base,还有一个派生类derived。我想用派生类中的类型覆盖基类中的类型。下面是一个例子:C++ 在派生类中重新定义typedef?,c++,inheritance,overriding,virtual,typedef,C++,Inheritance,Overriding,Virtual,Typedef,所以在搜索了很多问题的答案后,我最终放弃了我的谷歌技能 我有一个基类base,还有一个派生类derived。我想用派生类中的类型覆盖基类中的类型。下面是一个例子: class Apple { public: Apple() { } // ... }; class Orange { public: Orange() { } // ... }; class Base { public: typedef Apple fruit; // ..
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!
};
以上是我尝试过的解决方案之一。我还尝试在基类中创建一个虚拟嵌套类,并在派生类中重新定义,但该类也没有编译(它也非常混乱)
我也不能从同一个基类派生apple和Oranges,以返回指向base和Derived中父类的指针/引用。我需要实际返回对象的一个实例
首先,请看以下语法:
fruit func() override { return Orange(); }
什么是覆盖
?在C++03中,没有这样的关键字。它只在C++11中出现。因此,请确保您使用的编译器知道这个关键字
第二,在派生类中,fruit
确实是Orange
。重新定义typedef不是问题。问题是,Orange
和Apple
不是协变类型。从另一个派生将使它们协变。在您的情况下,您必须从苹果公司中派生出橙色,才能使其正常工作
注意,您必须将返回类型从水果更改为水果*
或水果&
class Orange : public Apple {}; //correct - your code will work
class Apple : public Orange {}; //incorrect - your code will not work
其思想是,在基类中,返回类型应该是基类(即Apple
)的指针/引用,而在派生类中,返回类型可以是Apple
类型的指针/引用或从其派生的任何类
顺便问一下,这有意义吗?从苹果
导出橙色
下面的课堂设计怎么样
class Fruit {};
class Apple : public Fruit {};
class Orange : public Fruit {};
class Base
{
virtual Fruit* f();
};
class Derived : public Base
{
virtual Fruit* f();
};
无需使用
typedef
您无法真正做到这一点,如果您有一个值对象,您必须知道它是哪种类型。(这是C++等静态类型语言和动态类型语言如露比和Python之间的主要区别之一)
有很多方法可以解决这个问题。首先,我们假设Apple
和Oragne
有一个名为Fruit
的公共基类。一种解决方案是使用new
动态分配对象,并返回一个Fruit
-指针
另一种解决方案是,函数不返回值,而是获取一个指向某个水果的指针或引用,然后填充该水果
另一个解决方案是使用某种容器对象,该对象内部可以容纳苹果或桔子。这样你就可以退货了。这一点从一开始就没有多大意义。
派生的
应该能够在任何需要基的地方使用,所以您应该能够这样做
Base *foo = new Base();
Apple x = foo->func(); // this is fine
Base *bar = new Derived();
Apple y = foo->func(); // oops...
我认为你需要研究一种不同的设计。现在还不清楚您的目标是什么,但我猜您可能希望Base
成为一个带有Fruit
作为模板参数的类模板,或者您需要完全摆脱继承。报告的错误告诉您所需的一切。这意味着Derived
方法中返回的类型需要从基方法中返回的类型派生
这样,如果基本方法被虚拟调用,则返回的对象可以被视为基本方法返回的对象
实际上,您需要返回一个指针或引用来执行此操作
您需要做的是定义一个新的Fruit
基类,并从中派生出Apple
和Orange
然后让func()
返回一个Fruit*
这将给您带来一个问题,即确保水果*
在某个时刻被删除
再加上一点上下文,我怀疑(可能是精简)模板是您所追求的解决方案,而不是继承。关键字override
通过让编译器检查函数是否确实重写了任何基本方法来帮助消除人为错误(如键入错误)。至于这个问题,我知道。有没有办法不用指针或引用就能使它们协变?所以我想没有办法让它工作。谢谢大家。我将尝试使用不同的层次结构。
Base *foo = new Base();
Apple x = foo->func(); // this is fine
Base *bar = new Derived();
Apple y = foo->func(); // oops...