我想从类生成一个shared_ptr并使用它来代替this * raw指针来初始化另一个。另一个期望在Constructor中使用shared_ptr。我只展示了一段摘录:
class Soundfile : std::enable_shared_from_this<Soundfile> { ...more code
std::shared_ptr<Soundfile> Soundfile::getptr() {
return shared_from_this();
}
我需要从Soundfile初始化另一个名为Channel inside的类:
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();
}
答案 0 :(得分:4)
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
来实现的。
如果您在shared_from_this
初始化之前致电weak_ptr
,则会引发bad_weak_ptr
异常,因为转化为shared_ptr
失败。
为了解决您的问题,您必须确保在shared_ptr
方法之前由getptr()
管理Soundfile的任何实例,或者调用调用它的任何方法。
在极少数情况下我使用shared_from_this
,我通常会将构造函数设为私有,并添加静态工厂方法以强制执行此操作:
class A {
public:
static std::shared_ptr<A> create() {
return std::make_shared<A>();
}
private:
A();
};
你仍然要小心你在构造函数中做了什么,因为shared_from_this
在它们内部不起作用。