C++ 使用来自此而不是此指针的共享\u

C++ 使用来自此而不是此指针的共享\u,c++,c++14,c++17,C++,C++14,C++17,我想从一个类生成一个共享的_ptr,并使用它而不是这个*原始指针来初始化另一个。另一个需要构造函数中的共享\u ptr。我只展示一段摘录: class Soundfile : std::enable_shared_from_this<Soundfile> { ...more code std::shared_ptr<Soundfile> Soundfile::getptr() { return shared_from_this(); } 类声音文件:std

我想从一个类生成一个共享的_ptr,并使用它而不是这个*原始指针来初始化另一个。另一个需要构造函数中的共享\u ptr。我只展示一段摘录:

class Soundfile : std::enable_shared_from_this<Soundfile> { ...more code

std::shared_ptr<Soundfile> Soundfile::getptr() {
     return  shared_from_this();
}
类声音文件:std::从\u启用\u共享\u此{…更多代码
std::shared_ptr Soundfile::getptr(){
从_this()返回共享的_;
}
我需要从Soundfile初始化另一个名为Channel inside的类:

bool Soundfile::openRead(const char *filename_) { 
//more code ...
     channels = std::make_shared<Channel>(getptr() , windowSize_, gdata);
}
bool声音文件::openRead(const char*filename_u2;){
//更多代码。。。
channels=std::make_shared(getptr(),windowSize_u,gdata);
}
这不起作用,我变成了一个弱ptr异常,我尝试了以下操作:

std::shared_ptr<Soundfile> Soundfile::getptr() {
    try {
        return shared_from_this();
    }
    catch (const std::bad_weak_ptr&) {
        return std::make_shared<Soundfile>();
    }
}
std::shared_ptr Soundfile::getptr(){
试一试{
从_this()返回共享的_;
}
捕获(常数标准::坏的\u弱的\u ptr&){
返回std::make_shared();
}
}
这是可行的,但我变成了一个新的空共享\u ptr,我在类Soundfile中保存了以前的数据,我需要在通道中使用它,因为这个原因,这不是我想要的。 我在这里搜索了一个解决方案,但我找不到,如果问题重复,很抱歉

编辑: 下面是我试图解释的一个小例子:

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();

}
class A:std::从\u启用\u共享\u{
公众:
A(){}
~A(){}
std::shared_ptr getptr(){
从_this()返回共享的_;
}
作废我的_方法(){
myB=std::使_共享(getptr());
}
私人:
std::共享_ptr myB;
};
B类{
公众:
B(标准::共享ptr_myA){
myA=_myA;
}
~B(){}
私人:
std::共享\u ptr myA;
};
int main(){
std::shared_ptr myA=std::make_shared();
myA->my_方法();
}

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

您可以将
enable_shared_from_this
视为一个包含
weak_ptr
的类。当将从
std::enable_shared_from_this
派生的类的实例传递给
shared_ptr
构造函数时,该构造函数将初始化其中的
weak_ptr
。从
调用
shared_s
仅在弱指针初始化后才起作用,因为它是通过将
弱ptr
转换为
共享ptr
来实现的

如果在初始化
弱\u ptr
之前从该共享\u,它将引发
坏\u弱\u ptr
异常,因为转换为
共享\u ptr
失败

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

在那些罕见的情况下,如果我使用此
中的
shared\u,我通常会将构造函数设置为私有,并添加静态工厂方法,以实现这一点:

class A {
    public:
        static std::shared_ptr<A> create() {
            return std::make_shared<A>();
        }
    private:
        A();
};
A类{
公众:
静态std::shared_ptr create(){
返回std::make_shared();
}
私人:
A();
};

您仍然必须小心在构造函数中执行的操作,因为
shared\u from\u this
在构造函数中不起作用。

std::enable\u shared\u from\u this::shared\u from\u this
仅当实例当前由共享指针管理时才起作用

您可以将
enable_shared_from_this
视为一个包含
weak_ptr
的类。当将从
std::enable_shared_from_this
派生的类的实例传递给
shared_ptr
构造函数时,该构造函数将初始化其中的
weak_ptr
。从
调用
shared_s
仅在弱指针初始化后才起作用,因为它是通过将
弱ptr
转换为
共享ptr
来实现的

如果在初始化
弱\u ptr
之前从该共享\u,它将引发
坏\u弱\u ptr
异常,因为转换为
共享\u ptr
失败

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

在那些罕见的情况下,如果我使用此
中的
shared\u,我通常会将构造函数设置为私有,并添加静态工厂方法,以实现这一点:

class A {
    public:
        static std::shared_ptr<A> create() {
            return std::make_shared<A>();
        }
    private:
        A();
};
A类{
公众:
静态std::shared_ptr create(){
返回std::make_shared();
}
私人:
A();
};

您仍然必须小心在构造函数中执行的操作,因为
shared\u from\u this
在构造函数中不起作用。

如何创建
Soundfile
实例?
shared\u from\u this()
仅适用于当前由
共享\u ptr管理的实例
声音文件是在另一个类中创建的,方法如下,
std::shared\u ptr file=std::make_shared();
文件->openRead(音频文件);
Channel是在openRead方法内部创建的。问题可能在于您没有显示的代码中的某个地方。为了获得进一步的帮助,请准备并显示一个。是的,我现在,类很大,我不能在这里复制整个类。不,错误在这一点上,在方法
内部初始化类通道的时候le->openRead
正如我指出的,我用以下方式更改了getptr方法
std::shared_ptr Soundfile::getptr(){try{return shared_from_this();}catch(const std::bad_弱_ptr&){return std::shared_ptr temp(this);}
现在通道的初始化工作正常,但我不确定这种方式是否最安全,这意味着调用
openRead
的实例毕竟不是由
共享的\u ptr
管理的,尽管您做出了相反的保证<