C++ 派生类的哪些虚拟重新声明是正确的?

C++ 派生类的哪些虚拟重新声明是正确的?,c++,C++,看起来正确的答案是“C”,但我不确定为什么。有人知道原因吗 编辑: 也就是说,哪个正确实现了多态性?选项A隐藏了原因Base::copy,而Derived::copy采用了不同类型的参数。对于选项D,基本的一个是const,其中派生的一个是non-const,两者没有相同的cv限定符。选项C使用相同的签名。所以c是正确的覆盖 选项C更改重写函数的默认参数。这被称为不良行为不应,而应是法律C++ 截至目前,协变返回类型B也是正确的,正如@Als所指出的 编辑:假设存在问题中未提及的virtual关

看起来正确的答案是“C”,但我不确定为什么。有人知道原因吗

编辑:


也就是说,哪个正确实现了多态性?

选项A隐藏了原因
Base::copy
,而
Derived::copy
采用了不同类型的参数。对于选项D,基本的一个是
const
,其中派生的一个是
non-const
,两者没有相同的cv限定符。选项C使用相同的签名。所以c是正确的覆盖

选项C更改重写函数的默认参数。这被称为
不良行为
不应
,而应是
法律C++

截至目前,协变返回类型B也是正确的,正如@Als所指出的

编辑:假设存在问题中未提及的
virtual
关键字

要更正选项A,它应该是

A. Base* Base::copy(Base*); 
   Base *Derived::copy(Derived*);

B. Base* Base::copy(Base*);
   Derived *Derived::copy(Base*);

C. ostream& Base::print(int,ostream&=cout);
   ostream& Derived::print(int,ostream&);

D. void Base::eval() const;
   void Derived::eval();
要更正选项D,它应该是

Base* Base::copy(Base*); 
Base* Derived::copy(Base*);


4个选项中没有一个覆盖基类函数。
按照C++标准,需要< <代码>虚拟< /COD>关键字来表示<强>重写< /强> ./p> 基本上,这4个函数都隐藏了相同命名函数的基类实现

这是函数隐藏而不是函数覆盖

读得好:

编辑:
假设存在
virtual
关键字,则答案是:
B

请注意,C是合法的,但不正确&OP要求正确的多态性实现,因此,
C:不符合正确条件。

重写函数应具有与其重写的函数相同的原型,请注意,重写函数允许具有

应用此规则,
A:
被取消资格,因为它使用不同的参数作为函数参数。
C:
被取消资格,因为您覆盖了许多函数。

D:
被取消资格,因为在函数上的
const
与没有
const
的函数不同

家庭作业?你有什么编程问题?没有。我正在读一本编程书。它有这个,我只是不能很好地理解这个。如果添加“virtual”关键字,那么你如何解释这个问题?我不明白为什么“C”是一个合适的多态性,而只是覆盖它。@Nohappy:答案是
B
,我已经更新了相关的详细信息。@Als,我删除了我的upvote,因为C也是正确的。这取决于“正确”的定义。在任何情况下,C都会触发覆盖,即
b->print
Base*b
将“正确”地”分派到
Derived::print
@Als:至于
C
它的a
不应该
坏习惯
,但我看到了链接中提到的合法性。返回类型不是函数签名的一部分。然而,这是一个普遍的做法,我保持它的基本类相同,你是正确的。我记得我曾经在C++编码标准或特殊C++中读到这篇文章,我忘记了。而且错过了。Thanks@Als在<代码>派生::g(int i=10)< /Cord>:它是“代码>是的,这是合法C++,是的,结果是明确定义的,并且不,不做它<代码>,这在数学上是正确的,但是很坏的实践。@ NealBasu,但是注意,你不能随意改变返回类型,它必须是原始返回类型的后代。@尼尔巴苏:恐怕我不同意,我已经恰当地说明了原因。
void Base::eval() const;
void Derived::eval() const;
void Base::eval();
void Derived::eval();