【问题标题】:C++ Inheritance: Variable with Type of a Base ClassC++ 继承:具有基类类型的变量
【发布时间】:2021-10-13 12:03:26
【问题描述】:

假设我们有两个类。

class Base {};

class Derived : public Base {};

在我的代码的另一部分,我想要一个Base 类型的变量,它也可以保存Derived 类型的对象。

Base b1, b2;
b1 = Base();
b2 = Derived();

在 Java 或 C# 等语言中,这是可能的。然而,在 c ++ 中,我得到一个切片错误。

有没有办法在 C++ 中复制例如 Java 的行为?

【问题讨论】:

  • 您是否熟悉其他语言中的值类型和引用类型?您是否熟悉 C++ 中的所有类在默认情况下本质上都是值类型的概念?你熟悉指针和引用吗?如果没有任何这些问题,那么您需要进行研究/学习。
  • 你可以复制行为,但代码会有所不同。

标签: c++ inheritance


【解决方案1】:

在 Java 和 C# 等语言中,对象变量是 reference 类型。 实际对象存储在动态内存中的某处,变量只是引用它们,就像指针一样。

但是在C++中,可以在自动内存、静态内存、动态内存等中创建对象。所以当你有一个对象变量时,那就是实际对象,而不是引用 到对象。

对于类型,没有办法让C++按照你想要的方式工作,只对引用类型。所以你必须使用指针/引用,否则slicing 将会发生,正如你已经发现的那样。多态性需要使用指针/引用来正确处理虚拟调度等。

Base b;
Derived d;
Base &b1 = b;
Base &b2 = d;
Base *b1 = new Base;
Base *b2 = new Derived;
...
delete b1;
delete b2;

【讨论】:

  • 所以如果我有一个函数foo(),它可以返回BaseDerived类型的值,我必须返回Base*?这是在 C++ 中执行此操作的正确方法吗?
  • @Luke 返回 std::unique_ptr<Base> 是为工厂函数执行此操作的正确方法(大多数情况下,这取决于销毁对象的责任所在)。
  • @Luke 是的,在这种情况下你必须返回一个(智能)指针。
【解决方案2】:

您可以使用指针来完成此操作,即这将起作用:

Base* bs=new Derived();

如果要调用Derived 中定义的函数,请执行以下操作:

((Derived*)bs)->fn();

【讨论】:

  • static_cast<Derived*>(bs)->fn(); 将是首选。将fn() 设为虚拟,这样就不需要演员阵容会更好。
猜你喜欢
  • 2019-03-28
  • 2021-09-28
  • 1970-01-01
  • 1970-01-01
  • 2013-04-19
  • 2015-12-09
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
相关资源
最近更新 更多