【问题标题】:Can't created a boost::shared_ptr from this无法由此创建 boost::shared_ptr
【发布时间】:2021-10-10 14:32:39
【问题描述】:

假设我有以下抽象类 A。现在我正在尝试从 A 类内部创建一个 shared_ptr 到 A。所以在 A 中我有以下功能:

class A {
    void A::setupArguments() const {
            ext::shared_ptr<A> ptr = ext::shared_ptr<A>(this);
        }
}

编译时报错

Error   C2440   'initializing': cannot convert from 'Y *' to 'A *

当shared_ptr函数定义为:

template<class Y>
explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
{
   boost::detail::sp_pointer_construct( this, p, pn );
 }

我在另一篇文章中读到这与明确的 shared_ptr 函数有关,其中参数 p 必须严格为 Y* 类型。在这种情况下,Y 引用 A 类,所以通过传入“this”,“this”不是因为它的类型为 A* 就已经足够明确了吗?我知道解决方案是使用 std::enable_shared_from_this 但我只想了解为什么这不起作用。例如,如果我们执行以下操作,它将起作用

ext::shared_ptr<A>(new A())

但是 new A() 不返回与 "this" 相同的类型吗?(都返回指向 A 的指针)那么为什么 new 可以工作而不是 "this"?

【问题讨论】:

  • 这是个坏主意。您不能将*this 的所有权移交给shared_ptr;这会让它的真正主人非常恼火。
  • ext::shared_ptr&lt;A&gt;(this); 永远不会是正确的。您不能创建指向随机指针的共享指针并期望它正常工作。你应该使用enabled_shared_from_this
  • @SergeyA 这很少是正确的,即使是,也有很大的代码味道,但 从不 不准确。在某些情况下以这种方式执行所有权转移是绝对可能的(想到与某些异步 C 库互操作)。
  • @Frank 这不是正确的代码 :) 在非常狭窄的情况下,该操作可能是有效的 :)

标签: c++ templates boost shared-ptr explicit


【解决方案1】:

由于setupArgumentsconst 限定函数,因此this 的类型为const A*。并且const A* 不能转换为A*,因此无法编译。

您需要使用shared_ptr&lt;const A&gt; 或删除const 限定符。

给出的完整错误应该如下所示:

error C2440: 'initializing': cannot convert from 'Y *' to 'A *'
        with
        [
            Y=const A
        ]
note: Conversion loses qualifiers

OT:从this 构造shared_ptr 时要小心,因为它可能导致双重删除。考虑使用boost::enable_shared_from_this

【讨论】:

  • 这个答案应该颠倒过来。任何关于使代码可编译的建议在这里都不适用,因为它是一个糟糕的代码。相反,答案应该集中在正确使用enable_shared_from_this,正如它最后提到的那样。
  • @Artyer 这有点棘手。从最严格的意义上讲,您的答案在“技术上”是正确的,因为它回答了 OP 提出的问题。然而,显而易见的是,如果 OP 将其集成到他们的代码中,它将导致未定义的行为和程序损坏。你真的需要用这些信息来限定你的答案,才能成为一个“好”的答案。
  • @Frank 并不总是导致未定义的行为(例如,(new A)-&gt;setupArguments(),或传递不调用 delete 的删除器)。虽然它不是最常见的,而且更有可能是错误的,但它仍然可能会被调用
  • 我实际上尝试更改为 shared_ptr 但得到另一个错误 Error C2440 '': cannot convert from 'boost::shared_ptr' to 'boost ::shared_ptr
  • @LewWeiHao 无论您在哪里使用过shared_ptr&lt;A&gt;,都必须更改为shared_ptr&lt;const A&gt;。或者您可以将其设为非常量函数并继续使用shared_ptr&lt;A&gt;
猜你喜欢
  • 2010-09-13
  • 2012-01-17
  • 2023-03-05
  • 2016-09-26
  • 1970-01-01
  • 1970-01-01
  • 2012-07-21
  • 1970-01-01
  • 2016-03-15
相关资源
最近更新 更多