我有这段代码(根据我现实生活中的麻烦设计的)
无法编译,提示 ExtendsB 没有实现 B::Run(A* a)
。但是,理解 A* Run();
class A { };
class ExtendsA : public A { };
class B
{
public:
virtual ~B(){}
virtual void Run(A* a) = 0;
virtual A* Run() = 0;
};
class ExtendsB : public B
{
public:
virtual ~ExtendsB(){}
// Not OK! It does not see it as an implementation of
// virtual void Run(A* a) = 0;
virtual void Run(ExtendsA* ea) {};
virtual ExtendsA* Run() { return new ExtendsA(); }; // OK
};
为什么 C++ 允许将返回类型更改为子类,但不允许更改参数类型?
这是一个很好的理由还是只是语言规范中的一个遗漏点?
最佳答案
Why C++ allows to change the return type to a sub-class, but not the parameter type?
C++ 标准允许您使用 Covariant return type 虽然覆盖了虚函数,但不允许你修改函数参数。是的,它背后有一个很好的理由。
Rationale:
重写本质上意味着在运行时将调用基类方法或派生类方法,具体取决于指针所指向的实际对象。
这意味着:
即:“可以调用基类方法的每个实例都可以通过调用派生类方法来替换,而无需更改调用代码。”
如果没有上述规则,它会留下一个窗口,通过添加新功能(新的派生类)来破坏现有代码。
如果派生类中的函数原型(prototype)与基类虚函数 w.r.t 参数不同,则该函数不会覆盖基类函数,因为上述规则已被破坏。
但是,协变返回类型不会违反此规则,因为向上转换是隐式发生的,并且基类指针始终可以指向派生类对象而无需任何转换,因此标准对返回类型强制执行协变返回类型的这一条件。
关于c++ - 在虚函数中使用子类类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12369206/