为啥在 C++ 中重写一次基方法会被调用

Posted

技术标签:

【中文标题】为啥在 C++ 中重写一次基方法会被调用【英文标题】:Why is base method being called once overridden in C++为什么在 C++ 中重写一次基方法会被调用 【发布时间】:2019-05-11 21:11:18 【问题描述】:

我有类似下面的情况(代码不准确,只是为了表达我的意思)。当我打电话给D.A() 时,我希望会打印出"Desc" 这个词,但会打印出"Base"

class Base 
public:
  void A()  B(); 
  virtual void B()  cout << "Base"; 


class Descendant : public Base 
public:
  virtual void B() overriden  cout << "Desc"; 


main () 
  Descendant D;
  D.A();

这里一定有一些概念性的东西。 D.A() 是否应该导致 "Desc" 被打印?如果不是,为什么?

【问题讨论】:

can't reproduce 使用显示的确切代码(在修复其中的拼写错误之后)。调用D.A() 会按预期显示"Desc"。不会发生的唯一方法是 1) A()/B()Base 构造函数/析构函数的上下文中被调用,或者 2) 如果 Descendant::B() 实际上没有覆盖 Base::B() (是 override 关键字旨在在编译时捕获的内容)。在后一种情况下,请确保您在实际代码中实际使用了 override(在 C++11 之前的版本中,没有 override)。 这是override,而不是overriden。这进一步巩固了此代码未经测试并且不会重现您的问题。请创建一个合适的minimal reproducible example。 @Storyteller - 正如我在问题中所说,这不是要编译的代码,只是表达我的问题的一种方式。它不应该编译 @Remy - 在你的 cmets 我做了一些追逐之后,我意识到 A 实际上是构造函数。这就解释了为什么后代 B 从未被调用过。 (我花了一段时间才找到)。 @TSG 那么您应该将其发布为答案,或者直接关闭问题。 【参考方案1】:

问题中有一个重要错误。方法 A 实际上是 Base 类的构造函数。构造函数不能调用派生类的任何方法(甚至是虚拟方法)是有道理的,因为这些派生类还不存在。

当 A 是非 ctor 时,它按预期工作。

【讨论】:

以上是关于为啥在 C++ 中重写一次基方法会被调用的主要内容,如果未能解决你的问题,请参考以下文章

从基类 C++ 调用重写的方法

Java 的 JPanel 子类中重写父类的 paint 方法 会被自动调用,请问调用的条件或时机

【彻底理解】 为啥重写equals()方法为啥要重写hashCode()方法

JAVA中重写equals方法为啥要重写hashcode方法说明

Java8中Stream类中的forEach是抽象方法,为啥在调用的时候不用重写该方法就能实现遍历?

C++编程中 子类(派生类)能不能重写父类(基类)的函数(方法),除了虚函数?