【问题标题】:Why we can do : Base *base = new Derived; while we can not do Derived *derived = new Base?为什么我们可以这样做: Base *base = new Derived;而我们不能做 Derived *derived = new Base?
【发布时间】:2020-04-18 16:13:41
【问题描述】:

现在假设基类包含一些函数,而派生类显然继承自基类... 所以派生类包含来自基类的函数加上它自己的一些额外的函数。因此我们不应该做Base *base = new Derived;,因为派生的函数比基数多,所以指向派生成员的基指针不应该是不可能的,因为它不能调用那些额外的派生函数。另一方面,Derived *derived = new Base 应该被允许,因为派生的指针可以包含来自 base 的所有函数而不会丢失任何数据,对吗? 那么为什么我们可以这样做:Base *base = new Derived;而我们不能做 Derived *derived = new Base ?

【问题讨论】:

  • 因为Base 对象不是Derived 对象?它没有Derived 对象应具有的任何函数或变量
  • “指向派生成员的 bass 指针应该是不可能的,因为它无法调用那些额外的派生函数” - 我看不到问题所在。为什么您无法访问一些可能可能存在的功能?
  • Base *bass = new Derived 是有效的,因为 DerivedBaseDerived *derived = new Base 无效,因为 Base 不是 Derived。对象类别(又名类)之间的“is-a”关系只向一个方向发展——例如,“狗是哺乳动物”始终是正确的陈述,但“哺乳动物是狗”并不总是正确的。除非 A 和 B 是相同的类别,否则没有任何类型的对象“A is-a B”和“B is-a A”都为真。

标签: c++ pointers inheritance


【解决方案1】:

任何Derived Base,但Base 不是Derived

如果你有一个像Animal 这样的基类,那么有一个由派生类Human 初始化的指针是很好的——人类可以做所有动物的事情。它一种动物。

但是你不能只用动物初始化指向人类的指针,因为当我们尝试将它用作人类时,它会丢失所有人类位,因为它只是作为基础动物创建的。

【讨论】:

  • 这就是我要说的。 Derived 是 Base,但 Base 不是 Derived,所以我可以做 Derived *derived = new Base
  • @VoIdProduction 既然Base 不是derived,那么您为什么期望能够拥有一个指向Base 实例的Derived *?它将丢失所有Derived 部分,使其不是有效的Derived *
  • @v 法拉利就是一辆汽车。但汽车不一定是法拉利。如果这辆车实际上是 Yugo,那么像法拉利一样驾驶它会以喜剧或灾难告终,具体取决于驾驶员。
【解决方案2】:

Jesper 已经很好地回答了这个问题,但我认为我可以通过回复您的具体示例来提供上下文

Derived *derived = new Base

然后你说“这应该被允许,因为派生指针可以包含所有来自 base 的函数而不会丢失任何数据,对吧?”

确实,如果您调用derived->SomeBaseMethod(),事情可能会起作用(理论上),但是如果您尝试调用仅存在于Derived 上的某些方法会发生什么? derived->SomeDerivedMethod()。由于指向的实际类型是Base 对象,因此没有派生方法可以执行。

现在,如果您有 Base* b = new Derived,那么编译器将只允许您在 b 上调用 base 方法(将为所有 Derived 对象定义),但不允许您调用任何派生方法,因为b 的类型是 base。因此,这将是安全的,而 Derived* d = new Base 则不会

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多