我的基类名为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>
的成员!
如果有人告诉我为什么会这样,以及如何解决它,我会感激不尽。
答案 0 :(得分:0)
(*vec.at(0))
将返回不知道Account
的{{1}}。您需要将x
指针强制转换为Account
以引用该成员。
Businessaccount
答案 1 :(得分:0)
不,在这种情况下不会发生切片,你的指针只是转换为指向基类的指针,即你的数据是相同的,只是改变了指针的类型。当切片发生时,你会丢失派生类的所有数据。
要解决此问题,您需要在基类中提供可在Businessaccount
中正确实现的虚拟方法,或使用dynamic_cast
或static_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 ++允许你使用你声称的那些(通过类型系统),然后让你编写自己的处理程序,如果你想要动态类型检查。