【问题标题】:Why doesn't std::enable_shared_from_this use a mutable std::weak_ptr?为什么 std::enable_shared_from_this 不使用可变的 std::weak_ptr?
【发布时间】:2020-10-08 04:44:22
【问题描述】:

我了解大多数标准库实现选择通过在基类中存储std::weak_ptr 来实现std::enable_shared_from_this。这导致以下结果:

#include <memory>

class Foo : public std::enable_shared_from_this<Foo>
{
public:
    std::shared_ptr<Foo> GetSharedBar() const
    {
        // returns shared_ptr<const Foo> instead of std::shared_ptr<Foo>
        return shared_from_this();
        // Error in VC++2019 due to mismatch.
    }
};

我似乎很清楚,尽管需要更新引用计数,shared_from_this() 实际上并没有改变目标对象。这似乎是可变对象的理想用途,因此可以将 shared_from_this() 相对于派生对象标记为 const。

为什么不用mutable实现?

为了阐明下面的答案:它是用标记为mutable 的std::weak_ptr 实现的,但这只允许std::weak_ptr 发生突变,而不是让我们将非const 交给其他人。

【问题讨论】:

  • @Eljay,你在使用 VC++ 吗?我更新了示例以包含重现我的观察所必需的所有内容。
  • 这种行为肯定是正确的吗?在GetSharedBar() 中,this 是指向const Foo 的指针。如果没有一些铸造恶作剧,你不可能将它作为指向非const Foo 的指针(包装在shared_ptr&lt;&gt; 或其他)中返回。
  • 嗯,我的理解是 std::enable_shared_from_this 包含指向 this 的 std::weak_ref,而不是 const this。如果weak_ref 被标记为可变的,我们就不能使用复制构造函数实例化一个指向它的std::shared_ptr 吗?
  • 我认为它按预期工作,如果您取出共享指针并尝试将this 作为非常量指针或引用返回,您将得到相同的错误
  • 为什么不用mutable实现?控制块是用mutable实现的。问题是方法需要是非常量,或者返回类型需要是std::shared_ptr&lt;Foo const&gt;,或者你需要return const_cast&lt;Foo*&gt;(this)-&gt;shared_from_this() 这是janky。

标签: c++ visual-c++ shared-ptr mutable enable-shared-from-this


【解决方案1】:

These both fail to compile:

class Foo : public std::enable_shared_from_this<Foo>
{
public:
    std::shared_ptr<Foo> GetSharedBar() const
    {
        // error: could not convert from 'shared_ptr<const Foo>' to 'shared_ptr<Foo>'
        return shared_from_this();
    }
};

class Bla
{
public:
    Bla* getThis() const
    {
        // error: invalid conversion from 'const Bla*' to 'Bla*'
        return this;
    }
};

但如果您从函数中删除 const,它们都可以工作。问题是在const 成员函数中,this 指针是const 指针。

再举一个例子:

class kluf
{
    const std::string* k;
    std::string* getK() 
    {
        // error: invalid conversion from 'const string*' to 'std::string*'
        return k;
    }
};

显然,您不能将const 成员交给非const 状态的其他人。这也适用于this 指针,在const 函数中this 是const。

【讨论】:

  • 谢谢,你的倒数第二句话本身就让我想到了这个问题!问题不是 std::weak_ptr 之一被变异,而是将非常量作为返回值传递给其他人。
猜你喜欢
  • 2015-03-14
  • 1970-01-01
  • 2012-05-04
  • 1970-01-01
  • 1970-01-01
  • 2014-12-17
  • 2016-08-03
  • 1970-01-01
  • 2012-10-04
相关资源
最近更新 更多