【问题标题】:Slicing when inserting pointer of derived class into vector of base class将派生类的指针插入基类的向量时切片
【发布时间】:2017-05-12 17:45:19
【问题描述】:

我的基类称为Account,而派生类Businessaccount 有一个额外的int 变量称为x,以及一个getter 方法(int getx())。 切片应该在以下情况下发生吗?这显然发生在我的案例中:

vector<shared_ptr<Account>> vec;
shared_ptr<Businessaccount> sptr = make_shared<Businessaccount>();

vec.push_back(sptr);

之后,如果我这样做:

(*vec.at(0)).getx();

它说class&lt;Account&gt; 没有名为getx() 的成员!

如果有人能告诉我为什么会发生这种情况以及如何解决它,我将不胜感激。

【问题讨论】:

  • 这不是切片,但是编译器当然是对的,at()返回的指针不能直接用来访问派生类的成员函数
  • Account 是否有名为 getx() 的成员?
  • 通过指针调用方法的典型方式是-&gt;运算符。 vect.at(0)-&gt;getx();.

标签: c++ object-slicing


【解决方案1】:

(*vec.at(0)) 将返回一个不知道xAccount。您需要将 Account 指针转换为 Businessaccount 以引用该成员。

shared_ptr<BusinessAccount> bA = dynamic_pointer_cast<BusinessAccount>(vec.at(0));
bA->getx();

【讨论】:

【解决方案2】:

不,在这种情况下不会发生切片,您的指针只是转换为指向基类的指针,即您的数据是相同的,只是指针的类型发生了变化。当切片发生时,您会丢失派生类的所有数据。

要解决这个问题,您要么需要在基类中提供可以在Businessaccount 中正确实现的虚方法,要么使用dynamic_caststatic_cast(如果您确定该对象具有Businessaccount 类型,则另当别论)。虽然使用这样的演员表通常是程序设计不佳的标志。

【讨论】:

    【解决方案3】:

    在 C++ 中,指向的对象的静态类型和动态类型可以不同。

    vec 中的共享指针指向的静态类型是Account

    该 vec 中的共享指针指向的动态类型会有所不同。在您的情况下,您将Businessaccount 放入其中。

    当您想要访问或调用方法时,您只能访问静态类型的方法。

    静态类型是您已向编译器证明该类型在该行包含的内容。

    如果知道得更多,你可以做一个static_cast&lt;Businessaccount*&gt;(vec.at(0).get())-&gt;getx()。通过这样做,您向编译器承诺您知道该位置的数据实际上是Businessaccount。如果你错了,你的程序的行为是不确定的(如果你很幸运,你会崩溃)。

    您还可以使用 RTTI(运行时类型信息)询问特定对象是否是特定子类型(在某些情况下,基类具有虚拟方法)。 p>

    Account* paccount = vec.at(0).get();
    Businessaccount* pba = dynamic_cast<Businessaccount*>(paccount);
    if (pba)
      pba->getx();
    

    上述检查paccount 是否实际上是Businessaccount*,如果是则调用getx。如果没有,它什么也不做。

    通常动态转换是您没有正确设计对象使用的标志;必须深入了解实现意味着您的接口可能不够丰富的接口。

    在某些脚本和字节码编译语言中,如果该方法不存在,它们会让您离开并调用 getx 并继续崩溃/抛出异常/等等。

    C++ 允许您使用您声称存在的内容(通过类型系统),然后如果您需要动态类型检查,您可以编写自己的处理程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-16
      • 2022-01-03
      • 1970-01-01
      • 2013-03-25
      • 2020-02-11
      • 1970-01-01
      相关资源
      最近更新 更多