将派生类的指针插入基类

时间:2017-05-12 17:45:20

标签: c++ object-slicing

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

int getx()

之后,如果我这样做:

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

vec.push_back(sptr);

它说(*vec.at(0)).getx(); 没有名为class<Account>的成员!

如果有人告诉我为什么会这样,以及如何解决它,我会感激不尽。

3 个答案:

答案 0 :(得分:0)

(*vec.at(0))将返回不知道Account的{​​{1}}。您需要将x指针强制转换为Account以引用该成员。

Businessaccount

答案 1 :(得分:0)

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

要解决此问题,您需要在基类中提供可在Businessaccount中正确实现的虚拟方法,或使用dynamic_caststatic_cast(如果您确定该对象具有类型) Businessaccount不同的事情)。虽然使用这样的演员阵容通常是没有精心设计的节目的标志。

答案 2 :(得分:0)

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

该vec指向的共享指针的静态类型为Businessaccount

该vec中共享指针的动态类型指向不同。在您的情况下,您将static_cast<Businessaccount*>(vec.at(0).get())->getx()放入其中。

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

静态类型是您在该行包含的编译器中证明的。

如果知道的更好,你可以Businessaccount。通过这样做,您向编译器承诺,您已经知道该位置的数据实际上是Account* paccount = vec.at(0).get(); Businessaccount* pba = dynamic_cast<Businessaccount*>(paccount); if (pba) pba->getx(); 。如果你错了,你的程序的行为是不确定的(如果你很幸运,你会崩溃)。

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

paccount

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

动态投射通常是你没有正确使用对象的标志;不得不深入了解实现意味着您的界面可能不够丰富的界面。

在某些脚本编写和字节码编译语言中,它们允许您启动并调用{{1}}并继续崩溃/抛出异常/ etc(如果该方法不存在)。

C ++允许你使用你声称的那些(通过类型系统),然后让你编写自己的处理程序,如果你想要动态类型检查。