虚函数输入参数类型

Virtual function input Argument type

我正在尝试了解继承和多态性。当我 运行 这个 :

    #include<iostream> 
    using namespace std; 

class Base 
{ 
int x; 
public: 
    virtual Base* fun() = 0; 
    int getX() { return x; } 
}; 

// This class inherits from Base and implements fun() 
class Derived: public Base 
{ 
    
public: 
    int y;
    Derived* fun() { 
        Derived *d = new Derived;
        d->y = 2;
        return d;
        
    } 
}; 

int main(void) 
{ 
    Derived d;
    Derived *p = d.fun();
  cout<< p->y;
} 

这很好用,因为派生 class 使用不同的 return 类型覆盖虚函数是合法的,只要 return 类型与原始 return类型

但是如果虚函数包含 Base* 类型的输入参数怎么办?喜欢:

#include<iostream> 
using namespace std; 

class Base 
{ 
int x; 
public: 
    virtual Base* fun(Base * t) = 0; 
    int getX() { return x; } 
}; 

// This class inherits from Base and implements fun() 
class Derived: public Base 
{ 
    
public: 
    int y;
    Derived* fun(Derived *t) { 
        Derived *d = new Derived;
        d->y = t->y;
        return d;
        
    } 
}; 

int main(void) 
{ 
    Derived d;
    Derived *p = d.fun();
  cout<< p->y;
} 

这是抛出错误 error: invalid new-expression of abstract class type ‘Derived’ Derived *d = new Derived;,据我所知,这意味着编译器无法识别虚函数的实现并将 class ``Derived``` 视为抽象。

那么我们如何覆盖这种类型的虚函数呢?? 我试图搜索它,但没有找到任何参考。如果存在类似问题,请告诉我。 谢谢

如果我在自己的代码中需要这个。我会这样写新的派生 class:

// This class inherits from Base and implements fun() 
class Derived: public Base 
{ 
    
public: 
    int y;
    Derived* fun(Base *t) { 
        Derived *d = new Derived;
        Derived* input = dynamic_cast<Derived *>(t);
        ASSERT(input);    // Cause the debug version to throw an exception so the error can be debugged
        if(input)
           d->y = t->y;
        else
           d->y = 0;    // Or the default of your choice. 
        return d;
        
    } 
}; 

如果传入的基类型不是正确的派生类型,这会引入潜在的运行时错误。但我没有找到避免它的方法。

我看到的其他选项是使用模板。派生类型需要传入派生类型的地方。或者简单地创建一个新函数,将派生类型作为输入并覆盖 fun(Base *t);

using namespace std;

template <class T>
class Base
{
    int x;
public:
    virtual T* fun(T* t) = 0;
    int getX() { return x; }
};

class Derived : public Base<Derived>
{

public:
    int y;
    Derived() { y = 0; }
    Derived* fun(Derived* t) {
        Derived *d = new Derived;
        d->y = t->y;
        return d;

    }
};

int main(int argc, const char* argv[])
{
    Derived *d = new Derived;
    Derived * p = d->fun(d);
    cout << p->y;
    return 0;
}

2019 年 visual studio 测试。