使用 share_from_this 而不是此指针

Use share_from_this instead of this pointer

本文关键字:指针 this share from 使用      更新时间:2023-10-16

我想从一个类生成一个shared_ptr,并使用它代替this*原始指针来初始化另一个。另一个期望在构造函数中shared_ptr。我只显示一段摘录:

class Soundfile : std::enable_shared_from_this<Soundfile> { ...more code
std::shared_ptr<Soundfile> Soundfile::getptr() {
return  shared_from_this();
}

我需要从 Soundfile 初始化另一个名为 Channel 的类:

bool Soundfile::openRead(const char *filename_) { 
//more code ...
channels = std::make_shared<Channel>(getptr() , windowSize_, gdata);
}

这行不通,我成了weak_ptr例外,我尝试执行以下操作:

std::shared_ptr<Soundfile> Soundfile::getptr() {
try {
return shared_from_this();
}
catch (const std::bad_weak_ptr&) {
return std::make_shared<Soundfile>();
}
}

这有效,但我变成了一个新的空shared_ptr,我将以前的数据保存在类 Soundfile 中,我需要在 Channel 中使用它,因此这不是我想要的。 我在这里搜索了一个解决方案,但我找不到,如果问题重复,对不起

编辑: 这是我试图解释的一个最小示例:

class A : std::enable_shared_from_this<A> {
public:
A() {}
~A() {}
std::shared_ptr<A> getptr() {
return shared_from_this();
}
void my_method() {
myB = std::make_shared<B>(getptr());
}
private:
std::shared_ptr<B> myB;
};
class B {
public:
B(std::shared_ptr<A> _myA)  {
myA = _myA;
}
~B() {}
private:
std::shared_ptr<A> myA;
};
int main() {
std::shared_ptr<A> myA = std::make_shared<A>();
myA->my_method();
}

std::enable_shared_from_this::shared_from_this仅在实例当前由共享指针管理时才有效。

您可以将enable_shared_from_this视为包含weak_ptr的类。将从std::enable_shared_from_this派生的类的实例传递给shared_ptr构造函数时,该构造函数将初始化其中的weak_ptr。只有在初始化弱指针后,调用shared_from_this才有效,因为它是通过将该weak_ptr转换为shared_ptr来实现的。

如果在初始化weak_ptr之前调用shared_from_this,则会引发bad_weak_ptr异常,因为强制转换到shared_ptr失败。

为了解决您的问题,您必须确保在调用getptr()方法或调用它的任何方法之前,Soundfile 的任何实例都由shared_ptr管理。

在我使用shared_from_this的极少数情况下,我通常会将构造函数设为私有并添加静态工厂方法来强制执行:

class A {
public:
static std::shared_ptr<A> create() {
return std::make_shared<A>();
}
private:
A();
};

你仍然必须小心你在构造函数中做什么,因为shared_from_this不会在构造函数中工作。