shared_ptr std::d ynamic_pointer_cast 失败,并显示“尝试引用已删除的函数”错误

shared_ptr std::dynamic_pointer_cast fails with "attempting to reference a deleted function" error

提问人:Sami 提问时间:3/20/2023 最后编辑:Sami 更新时间:3/20/2023 访问量:322

问:

我已经在 StackOverflow 中看到了关于这个类似错误的所有帖子,但仍然找不到导致我出现问题的原因。

我正在使用将对象强制转换为对象,但遇到“尝试引用已删除的函数”错误。我已经确保析构函数是虚拟的,但错误仍然存在。std::dynamic_pointer_caststd::shared_ptr<Base>std::shared_ptr<DerivedShared>Base

是什么原因导致了此错误,我该如何解决?标准库中是否有任何可能导致此问题的已知限制或错误?任何见解或建议将不胜感激。

PS : 我知道它适用于,但想知道是什么导致了dynamic_pointer_cast的问题!static_pointer_cast

struct Base
{
    Base() = default;
    virtual ~Base() = default;
    //Copy
    Base(const Base&) = default;
    Base& operator=(const Base&) = default;
    //Move
    Base(Base&&) = default;
    Base& operator=(Base&&) = default;
};


struct DerivedShared : public  Base
{
public:
    DerivedShared() //: data(std::shared_ptr<int[]>(new int[3]{1,2,3}))
    {
        //data = std::make_shared<int[]>(new int[3]{ 1,2,3 });
        data = std::shared_ptr<int[]>(new int[3]{ 1,2,3 });
    }
    
public:
    std::shared_ptr<int[]> data;
};

int main()
{
    std::cout << "----------------------------------------\n";
    std::shared_ptr<Base> base5 = std::make_shared<DerivedShared>();
    for (size_t i = 0; i < 3; ++i)
    {
        std::cout << std::dynamic_pointer_cast<DerivedShared>(base5)->data[i] << '\n';
    }
}
C++ 共享 PTR 动态转换

评论

0赞 user17732522 3/20/2023
在我测试的所有编译器上编译没有错误:godbolt.org/z/z7rKTaaKj
0赞 Sami 3/20/2023
它给了我编译时错误!项目严重性代码描述行文件抑制状态沙盒错误 C2280 'std::shared_ptr<DerivedShared> std::d ynamic_pointer_cast<DerivedShared,Base>(const std::shared_ptr<Base> &) noexcept':尝试引用已删除的函数。尝试使用 C++ 14 直到 C++ 23 但不起作用
2赞 ALX23z 3/20/2023
您可能已在编译器中禁用了 RTTI 或出现其他一些构建问题。
3赞 user17732522 3/20/2023
是的,这是禁用 RTTI 时的分支 (github.com/microsoft/STL/blob/main/stl/inc/memory#L2049)。您不能在禁用 RTTI 的情况下使用。问题是你为什么首先禁用它?#elsedynamic_cast
2赞 user17732522 3/20/2023
@Sam 那么我建议问问你的教授,他是否故意禁用了RTTI,如果是的话,为什么,以及你应该如何在没有它的情况下工作。默认情况下,它应该被启用,因为它是标准 C++ 语言的一部分,一些核心语言功能,如果没有它,它将无法工作。(尽管由于各种原因,它经常被禁用,例如在嵌入式开发中。dynamic_casttypeid

答:

8赞 user17732522 3/20/2023 #1

您禁用了 RTTI,在这种情况下,Microsoft 的标准库实现定义为已删除,因为没有 RTTI 就无法工作。(见 https://github.com/microsoft/STL/blob/main/stl/inc/memory#L2049。std::dynamic_pointer_castdynamic_cast)

如果要使用 ,则无法禁用 RTTI。std::dynamic_pointer_cast