首页 > 解决方案 > 在使用共享指针调用的函数中使用 this 是有效的

问题描述

我有一个关于在 C++ 中使用共享指针和多线程编程的问题。如果我在线程 A 中使用此类的共享指针对象调用成员函数,那么在类中使用 this 属性并将 this 传递到将从线程 B 触发的回调函数中是有效的。从我的角度来看,如果线程A 完成它的工作然后共享指针将过期并且这将是无效的。

使用 shared_from_this 并将其强制转换为 void* 是否有效?

你好这里是代码。这段代码会产生分段错误,对吧?

#include <memory>
#include <iostream>
#include <thread>
#include <unistd.h>
#include "ClassB.h"
class B;
class A
{
public:
        A()= default;

        void foo(void * ptr)
        {
            std::cout <<"enter in foo" <<std::endl;
            sleep(1);
            std::cout << "Thread wake up" << std::endl;
            B *pB = reinterpret_cast<B*>(ptr);
            pB->x = 5;
        }
};

void B::bar()
{
    std::cout << "enter in bar" << std::endl;
    void * ptr = reinterpret_cast<void *>(this);
    auto t2= std::thread(&A::foo,A(),ptr);
    t2.detach();
}

void threadTask()
{
    std::cout << "ThreadTask" << std::endl;
    std::shared_ptr<B> psharedB = std::make_shared<B>();
    auto t1 = std::thread(&B::bar,psharedB);
    t1.detach();
}

int main()
{
    auto t = std::thread(threadTask);
    t.join();
    sleep(20);

    return 0;
}

谢谢乔治

标签: c++shared-ptr

解决方案


如果对象是在堆上分配的( using new),如果线程完成,它不会变得无效。shared_pointer存储一个指向堆上实例的指针和一个指向计数变量的指针。如果shared_pointer被复制,计数变量会增加,如果调用它的析构函数,它会减少。如果计数为 0,则对象的析构函数由共享指针调用,因此如果不再有shared_pointers 指向该对象。shared_pointer应该是线程保存,即使这是非常资源密集型的。重要的是要知道,如果您将指针传递shared_pointershared_pointer现在负责管理实例,但它不涉及指针的任何其他用法。因此,您不应在指向该对象的其他指针上调用 delete。因此,如果您使用 分配对象,它不应该引起任何冲突new

编辑:

这不应该起作用,shared_pointer因为当线程分离并且范围离开并且count=1 B应该被销毁时,将被销毁。分离线程总是一个坏主意。


推荐阅读