【问题标题】:Is it safe to use such smart pointer casting?使用这种智能指针转换是否安全?
【发布时间】:2011-12-05 10:27:11
【问题描述】:

使用这种智能指针转换是否安全?

APtr a(new A());
BPtr & b = (Bptr&)a; // this is it

那里,

class A
{
public:
   virtual ~A(){}
   virtual void methodA() = 0;
}
typedef std::tr1::shared_ptr<A> APtr;

class B : public A
{
public:
   virtual ~B(){}
   virtual void methodB() = 0;
}
typedef std::tr1::shared_ptr<B> BPtr;

/////////////////////////////////////////////////////////////////////////////////

BPtr & b = a; //this way doesn't work

【问题讨论】:

  • 为什么不直接使用BPtr b = a;
  • @KennyTM:并非每个 A 都是 B。事实上,所讨论的 A (a) 肯定不是。
  • @MarceloCantos:抱歉,将代码读作 B 是 A 的基类。
  • @student023:您的a 不是B 的实例,那么您想通过将其视为一个实例来实现什么?
  • ¤ 您显示的代码无法编译。所以安全问题没有实际意义,或者说,try 是完全安全的。请询问可以编译的内容。

标签: c++ casting smart-pointers tr1


【解决方案1】:

要向下转换智能指针,您应该使用 xxxx_pointer_cast 函数,例如static cast

BPtr b = std::tr1::static_pointer_cast<B>(a);

dynamic cast

BPtr b = std::tr1::dynamic_pointer_cast<B>(a);

【讨论】:

    【解决方案2】:

    是否安全是另一个问题。当还强制尝试使其成为哑指针时,将智能分配给其他类型的引用绝对是不寻常的并且不可能。

    我认为您需要先弄清楚这些类型是什么。然后。好吧,如果你坚持要问,你未来的问题的答案很可能是“不”。

    【讨论】:

      【解决方案3】:

      编辑:修改这个答案(因为它被再次挖掘并且已经过去了很长时间)。

      AB 可能有继承关系,但shared_ptr&lt;A&gt;shared_ptr&lt;B&gt; 没有。 shared_ptr 是一个模板类,A 的模板实例化与B 的实例化无关。

      使用类似 C 的强制转换(或 reinterpret_cast)有效,但这只是因为您正在强制重新解释底层位。两个不同的 shared_ptr 实例上的 dynamic_cast 将失败,因为您没有转换继承的指针,而是尝试转换完全不同且不兼容的类型的智能指针。

      对于您提出的问题,答案是(仍然)否。

      【讨论】:

      • 永远不要说永远!你不知道人们为什么使用dynamic_cast吗?我知道这是一个旧答案,但它也是错误的。
      • 我永远不会。原始代码使用类似 C 的强制转换,它或多或少是对两种不同类型的 reinterpret_cast。由于模板的性质,shared_ptr 与 shared_ptr 没有继承关系。这就是BPtr &amp; b = a; //this way doesn't work 的原因。两个 typedef 上的 dynamic_cast 也应该引发异常,因为 BPtr 和 APtr 不是继承关系。
      • 我了解 OP 给出的示例是一个糟糕的转换示例。但是你说“从不”并不符合正确的陈述。我真的需要说明必须转换为派生的示例吗?考虑经典的BaseAbstractClass* clone() 方法的情况。前几天我在 Qt 中使用QIconEngine 遇到了这种情况。您会得到克隆,它基本上是内部派生的,但具有基本指针类型。如果你不把它转换成派生的,那就没用了。我并不是说您对 OP 的情况有误,但“从不”对于这个主题来说是一个非常强烈的词,并且不适用。
      • 不错,我修改了答案。 OP 的前两行让我有点困惑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-03
      • 1970-01-01
      • 2011-06-14
      • 2012-01-27
      • 1970-01-01
      相关资源
      最近更新 更多