Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在派生类中重新定义typedef?_C++_Inheritance_Overriding_Virtual_Typedef - Fatal编程技术网

C++ 在派生类中重新定义typedef?

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; // ..

所以在搜索了很多问题的答案后,我最终放弃了我的谷歌技能

我有一个基类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!
};
以上是我尝试过的解决方案之一。我还尝试在基类中创建一个虚拟嵌套类,并在派生类中重新定义,但该类也没有编译(它也非常混乱)

我也不能从同一个基类派生apple和Oranges,以返回指向baseDerived中父类的指针/引用。我需要实际返回对象的一个实例

  • 有什么方法可以声明抽象typedef吗
  • 如果没有,是否有其他解决方案可以实现我的目标 想做什么

  • 首先,请看以下语法:

    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...