gpt4 book ai didi

c++ - 多重继承调用 shared_from_this 导致的 Bad_weak_ptr

转载 作者:行者123 更新时间:2023-11-30 04:44:33 44 4
gpt4 key购买 nike

我想了解为什么在调用 shared_from_this 时会出现 bad_weak_ptr 异常。

#include <memory>
#include <iostream>

class parent : public std::enable_shared_from_this<parent>
{
public:
void compare(std::shared_ptr<parent> const& p2)
{
std::cout << (this->shared_from_this() == p2->shared_from_this());
}
};

class child1 : public parent
{};

class child2 : public parent
{};

class child3 : public child1, public child2
{};

void compare(parent& p1, parent& p2)
{
std::cout << &p1 << " : " << &p2 << "\n";
std::cout << (&p1 == &p2);
}

void compare(std::shared_ptr<parent> const& p1, std::shared_ptr<parent> const& p2)
{
compare(*p1, *p2);
// p1->compare(p2); // bad_weak_ptr
// auto p = p1->shared_from_this(); // bad_weak_ptr
}

void compareusingchild(std::shared_ptr<child1> const& c1, std::shared_ptr<child2> const& c2)
{
compare(c1, c2);
}

int main()
{
std::shared_ptr<child3> c3 = std::make_shared<child3>();
try
{
compareusingchild(c3, c3);
}
catch (std::exception& e)
{
std::cout << e.what();
}
return 0;
}

我发现通过使 class parent 继承虚拟化,这个问题似乎不会持续存在。为什么这不是编译时错误?当找不到正确的继承父级时,类似于“模棱两可的函数调用”?

仅包含父类的 API 无法预先知道继承层次结构,调用比较方法(在父类中)将导致运行时错误。是否有可能使编译时检测到此类错误?

最佳答案

好的,现在我知道问题出在哪里了。

菱形继承(钻石问题)禁用shared_from_this() .

在引擎盖下(对于 MSVC 2017)你可以找到这样的东西:

template<class _Yty,
class = void>
struct _Can_enable_shared
: false_type
{ // detect unambiguous and accessible inheritance from enable_shared_from_this
};

template<class _Yty>
struct _Can_enable_shared<_Yty, void_t<typename _Yty::_Esft_type>>
: is_convertible<remove_cv_t<_Yty> *, typename _Yty::_Esft_type *>::type
{ // is_convertible is necessary to verify unambiguous inheritance
};

所以基本上当生成模板时,它会检查是否从 child3 * 转换而来至 std::enable_shared_from_this<parent> *是可能的。如果可能,则设置内部弱指针,否则什么都不做。

现在由于存在歧义,简单的转换是不可能的 std::is_convertible返回 false 和 shared_from_this未启用(设置为适当的值)。

这是一个证明:https://godbolt.org/z/V2AzLk

        std::cout << "Conv child3: " << std::is_convertible<child3*, std::enable_shared_from_this<parent>*>::value << std::endl;
std::cout << "Conv child2: " << std::is_convertible<child2*, std::enable_shared_from_this<parent>*>::value << std::endl;
std::cout << "Conv child1: " << std::is_convertible<child1*, std::enable_shared_from_this<parent>*>::value << std::endl;

打印:

Conv child3: 0
Conv child2: 1
Conv child1: 1

所以基本上歧义不会导致编译问题,它只是不会启用此功能。

关于c++ - 多重继承调用 shared_from_this 导致的 Bad_weak_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57706912/

44 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com