为什么std :: enable_shared_from_this不使用可变的std :: weak_ptr?

问题描述

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

#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来实现?

为阐明以下答案:它用标记std::weak_ptr的{​​{1}}实现,但这仅允许mutable进行突变,而不能让我们交出非{ {1}}给其他人。

解决方法

https://reactjs.org/docs/faq-state.html#what-does-setstate-do

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函数中,thisconst