gpt4 book ai didi

c++ - shared_ptr 问题从成员函数返回向上转换版本

转载 作者:太空狗 更新时间:2023-10-29 20:17:59 25 4
gpt4 key购买 nike

我最近一直在试用 shared_ptr 并且遇到了一些奇怪的情况。我想要的是一个模板成员函数,它能够返回其派生类型的 shared_ptr。我正在运行 visual studio 2010,它可以访问一些新的 c++0x 标准,但我假设 boost shared_ptr 的行为类似。

这对裸指针来说效果很好。我刚刚返回了一个 dynamic_cast (this)。然而,我在这里有点难过,因为即使使用 enable_shared_from_this 对象也会在调用函数后尝试删除自身(这很糟糕)。我可能正在接近这个错误,但我想弄清楚如何模拟以下(这是我遇到问题的代码)的裸指针等效项(正在运行)。

//assume we have a virtual function as well.
class BaseClass : public std::enable_shared_from_this<BaseClass>
{
....
template<typename DerivedClass>
std::shared_ptr<DerivedClass> BaseClass::getThis(){
//I had some assert code here to ensure typeid matched
return std::dynamic_pointer_cast<DerivedClass>(shared_from_this());
}
}

编辑:功能似乎正常工作,问题出在我的使用方式上。这是不好的,例如执行以下操作:

std::shared_ptr<DerivedClass> p = std::make_shared<DerivedClass>();
p->getType<DerivedClass>->someOtherFunctionOnlyInTheDerivedClass();

这不是问题:

std::shared_ptr<BaseClass> p = std::make_shared<DerivedClass>();
p->getType<DerivedClass>->someOtherFunctionOnlyInTheDerivedClass();

我不完全确定是转换为相同类型的问题,还是引用计数的问题。在任何情况下,我都在做一些愚蠢的事情并且它坏了,避免不必要的 getType 调用在我使用它的所有其他情况下似乎都可以正常工作。也许有人可以准确解释是什么导致第一个示例与第二个示例一起工作。我会为该答案分配分数。

最佳答案

为了扩展 Stuart 的回答并(可能)解释您崩溃的原因,我最好的猜测是您在堆栈分配的实例上调用了 getType。这是使用 enable_shared_from_this 的一个主要缺陷。

#include <memory>

class Base : public std::enable_shared_from_this<Base>
{
public:
virtual ~Base() {}

template <typename D>
std::shared_ptr<D> getType()
{
return std::dynamic_pointer_cast<D>(shared_from_this());
}
};

class Derived : public Base
{
public:
void f() {}
};

int main()
{
std::shared_ptr<Derived> d = std::make_shared<Derived>();
d->getType<Derived>()->f(); // fine

Derived d2;
Base* p = &d2;
p->getType<Derived()>->f(); // will attempt to delete d2 after f() returns.

return 0;
}

发生这种情况的原因是 d2 在堆栈上时的引用计数为零。调用 shared_from_this 返回一个 shared_ptr 将引用计数递增到 1。一旦该指针超出范围,它会将其计数递减为零,然后尝试删除该实例,该实例当然在堆栈中。

我能想到的保护自己不受此影响的唯一方法是使所有构造函数 protected 或私有(private),并提供动态分配任何实例的静态函数,返回 shared_ptr s,当然。

关于c++ - shared_ptr 问题从成员函数返回向上转换版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5458302/

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