【问题标题】:dynamic_cast across a shared_ptr?跨shared_ptr的dynamic_cast?
【发布时间】:2014-05-21 23:02:56
【问题描述】:

我有两个类 A 和 B,B 继承自 A。

如果我有一个 shared_ptr<A> 对象,我知道它确实是 B 子类型,我如何执行动态转换来访问 B 的 API(记住我的对象是 shared_ptr,而不仅仅是 A?

【问题讨论】:

    标签: c++ polymorphism shared-ptr dynamic-cast


    【解决方案1】:

    如果您只想从B 调用一个函数,您可以使用以下方法之一:

    std::shared_ptr<A> ap = ...;
    dynamic_cast<B&>(*ap).b_function();
    if (B* bp = dynamic_cast<B*>(ap.get()) {
        ...
    }
    

    如果你真的想从std::shared_ptr&lt;A&gt; 获得std::shared_ptr&lt;B&gt;,你可以使用 use

    std::shared_ptr<B> bp = std::dynamic_pointer_cast<B>(ap);
    

    【讨论】:

    • dynamic_cast&lt;B&amp;&gt;(*ap).b_function(); 如果你这样做,那么 dynamic_cast 的意义何在。无论如何您都不检查结果,您只需在此处使用static_cast。我认为这里只有if(B* bp = ...dynamic_pointer_cast 是正确的。
    • @FantasticMrFox:只有当a 是从B* 的隐式转换中获得时,才能使用static_cast&lt;B*&gt;(a)。在涉及多重继承的场景中,转换来自进一步的派生类型或兄弟类,dynamic_cast 已定义行为,而 static_cast 未定义。
    【解决方案2】:

    使用dynamic_pointer_cast

    从上述链接复制的示例

    // static_pointer_cast example
    #include <iostream>
    #include <memory>
    
    struct A {
      static const char* static_type;
      const char* dynamic_type;
      A() { dynamic_type = static_type; }
    };
    struct B: A {
      static const char* static_type;
      B() { dynamic_type = static_type; }
    };
    
    const char* A::static_type = "class A";
    const char* B::static_type = "class B";
    
    int main () {
      std::shared_ptr<A> foo;
      std::shared_ptr<B> bar;
    
      bar = std::make_shared<B>();
    
      foo = std::dynamic_pointer_cast<A>(bar);
    
      std::cout << "foo's static  type: " << foo->static_type << '\n';
      std::cout << "foo's dynamic type: " << foo->dynamic_type << '\n';
      std::cout << "bar's static  type: " << bar->static_type << '\n';
      std::cout << "bar's dynamic type: " << bar->dynamic_type << '\n';
    
      return 0;
    }
    

    输出

    foo's static  type: class A
    foo's dynamic type: class B
    bar's static  type: class B
    bar's dynamic type: class B
    

    【讨论】:

    • 那个例子甚至不需要任何演员表。
    【解决方案3】:

    可能最好的方法是 use the standard functions 用于投射 shared_ptr

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-13
      • 2020-10-25
      • 2018-04-29
      • 2011-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多