class Base
{
bool a;
};
class Derived : public Base
{
bool b;
};
void main()
{
std::shared_ptr<Base> base(new Derived());
}
因此,在此示例中,shared_ptr的原始指针将指向Base的实例,NOT Derived。我不明白。
class Base
{
virtual void foo() {}
bool a;
};
class Derived : public Base
{
virtual void foo() {}
bool b;
};
void main()
{
std::shared_ptr<Base> base(new Derived());
}
但是在这种情况下,shared_ptr的原始指针确实指向Derived?我确定我错过了什么。有人可以向我解释为什么会这样吗?
答案 0 :(得分:2)
在第一个示例中,类没有虚拟表,因为没有虚函数。 这意味着,由于shared_ptr需要一个静态类型的Base,它将存储一个Base。 第二种情况也存储Base,但是存在虚拟表允许您看到对象的动态类型是Derived。
答案 1 :(得分:1)
首先,这里使用std::shared_ptr
是一个红鲱鱼。在
在这种情况下,std::shared_ptr
和原始指针都表现出来
完全相同的。在这两种情况下,表达式new Derived()
返回指向整个对象的Derived*
。并在
两种情况,用它来初始化指向Base
的指针,就是这样
原始指针或任何合理设计的智能指针
导致Derived*
转换为Base*
,指向
到Base
中的Derived
子对象。 Derived
对象
但是,仍然存在,可以通过几种不同的方式访问
方式:通过虚拟功能,使用std::dynamic_cast
if
Base
是多态的(至少有一个虚函数),by
使用std::static_cast
,如果您100%确定指向
对象实际上是Derived
,可能还有其他一些我
没有想到。在你的第一种情况下,只有最后一种是可能的,
因为在第一个中,Base
不是多态的。在你们两个
但是,示例指针指向Base
,即
较大的Derived
。
std::shared_ptr
与原始版本之间存在一些差异
指针。例如,在您的第一个示例中,替换
std::shared_ptr<Base>
Base*
并std::shared_ptr
并手动删除
通过指针将导致未定义的行为;
Base
有额外的复杂功能可以避免这种情况。 (但
并发症没有它们的缺点。给Derived
一个虚拟的析构函数,它应该有,然后制作
{{1}}私有的析构函数,出于任何奇怪的原因,
并且你的第一个例子不会编译。)