在基类指针容器中访问派生类对象的正确方法是什么?

时间:2012-02-01 08:18:28

标签: c++ stl smart-pointers

我有一个vector<boost::shared_ptr<Base>>个对象。我正在插入Derived类型的对象,其中Derived继承Base,如下所示:container.push_back(boost::shared_ptr<Base>(new Derived()));

我现在想调用一个引用Derived成员的函数,以便修改我刚插入的最后一个条目。这样,我最终不会创建此Derived对象的临时实例。这就是我能够做到的:func(static_cast<Derived*>(&*container.back())->member);

这对我来说真的很可怕。但是如果我尝试改为func(static_cast<Derived>(*container.back()).member);,编译器说我需要为Derived提供一个ctor,它接受args (const Base&)以便将Base的实例转换为Derived的实例,我不需要在这里做...我只想引用我的shared_ptr指针,好像它是Derived*,因为我知道这是因为我只是new编辑它。

3 个答案:

答案 0 :(得分:3)

vector<boost::shared_ptr<Base>> container;

shared_ptr<Derived> ptr(new Derived());
container.push_back(ptr);
func(ptr->member);

没有演员。没有临时的Derived

答案 1 :(得分:1)

我会使用dynamic_cast<>,因为存储的对象实际上可能不是Derived类型(它可能是Derived_2也是从Base派生的)。

func(dynamic_cast<Derived&>(*container.back()).member)

您还可以转换为引用,使其看起来更整洁。

注意:dynamic_cast<>

  • 如果用于转换指针可能会返回NULL
  • 如果用于转换引用可能会抛出std :: bad_cast

这就是为什么我更喜欢通常使用带引用的dynamic_cast。但是如果你将它与指针一起使用,请确保在使用它之前检查结果是否为NULL。

编辑更新的问题:

  

但是如果我尝试做func(static_cast(* container.back())。member);

你想要一个参考

static_cast<Derived&>
                  ^^^  Not the & here

这将阻止它尝试调用构造函数。如果你static_cast&lt;&gt;派生它将尝试创建一个对象。你真正想要的是一个参考。

答案 2 :(得分:0)

您可以使用static_pointer_castdynamic_pointer_castshared_ptr之间进行广告投放:

shared_ptr<Derived> sp = static_pointer_cast<Derived>(container.back());