我试图在一个类函数中创建和使用一个std::shared_ptr
,该函数的构造函数接受一个std::shared_ptr
私有数据成员(属于同一个类)和另一个std::shared_ptr
,该std::shared_ptr
是用指向类对象的原始指针(this
)创建的。
每当我调用创建std::shared_ptr
(foo
)的函数时,我都会得到一个_CrtIsValidHeapPointer(block)
Assert。我假设它与删除shared_ptr
的方式有关,但我似乎找不到答案,我在互联网上搜索了所有的地方。也许我没有完全理解shared_ptr
是如何工作的。
使用this
指针或预先存在的shared_ptr
数据成员创建shared_ptr
是否不可接受?
class Containing_Class;
class Some_Class
{
};
class Set_Value_Command
{
public:
Set_Value_Command(std::shared_ptr<Some_Class> ptr1, std::shared_ptr<Containing_Class> ptr2)
: _ptr1(ptr1), _ptr2(ptr2)
{}
private:
std::shared_ptr<Some_Class> _ptr1;
std::shared_ptr<Containing_Class> _ptr2;
};
class Containing_Class
{
public:
Containing_Class(std::shared_ptr<Some_Class> psc)
: _psc(psc)
{}
void foo()
{
std::shared_ptr<Set_Value_Command> command = std::make_shared<Set_Value_Command>(_psc, std::shared_ptr<Containing_Class>(this));
}
private:
std::shared_ptr<Some_Class> _psc;
};
下面是main()
函数。当foo()
被调用时,Assert发生:
int main()
{
std::shared_ptr<Some_Class> some_class = std::make_shared<Some_Class>();
Containing_Class cc(some_class);
cc.foo();
}
2条答案
按热度按时间qq24tv8q1#
使用
this
指针创建shared_ptr
是否不可接受不是单独的,不。在你的例子中这样做是非常糟糕的。你的
Containing_Class
对象是在main()
的本地堆栈帧的自动内存中创建的。因此当main()
退出时,当它超出范围时将被自动销毁。但是在Containing_Class
对象内部从this
创建shared_ptr
会将this
的所有权分配给shared_ptr
,然后当不再有对this
的shared_ptr
引用时delete
将尝试this
。delete
对不是以new
创建的对象进行开始是 * 未定义行为 *,这就是为什么您会因为一个关于无效堆指针的错误而崩溃。为了允许
shared_ptr
引用this
,Containing_Class
需要从std::enable_shared_from_this
派生,并且this
必须指向一个动态创建并由shared_ptr
拥有的对象。只有这样,Containing_Class
才能调用其继承的shared_from_this()
方法来获得shared_ptr
。例如:
3pvhb19x2#
有了密码
引入第二个
*this
所有者,即command
是控制cc
寿命的共享指针的所有者。这是第一个问题。还有另一个问题,接下来的问题是command
指向堆栈对象。通常
*this
由某人所有,将所有权传递给另一个所有者是行不通的。由于缺乏代码目标,当前代码无法修复。