如何将智能指针从函数传递给调用者?

问题描述

我正在尝试掌握C ++中智能指针的概念。我有以下代码(使用GoogleTest进行单元测试):

<div class="main-container">
  <h1>Hi</h1>
  <svg class="morph" viewBox="168 140 1065 600" preserveAspectRatio="none">
    <path d="M735.75,229.593c61.129-5.951,122.258-90.759,179.219-89.271s127.815,53.562,166.715,72.9,140.318,49.1,148.654,130.931-16.672,141.346-13.893,187.469,11.114,196.4-186.165,193.42-220.9-122-327.873-89.271-104.2,111.588-308.423,89.271S136.965,405.159,184.2,356.06s33.343-117.54,112.533-119.028,138.929-37.2,205.615-38.684S674.622,235.544,735.75,229.593Z" fill="#EFE9F5" opacity="0.5"/>
  </svg>
</div>

我想隔离测试的前五行以使它们可以重用。我认为这样做就足够了(尤其是正确的):

TEST(SHT35Sensor,ValidInstruction) {
    auto sht35 = SampleSHT35::create();
    sht35->add(22.4,56.5);
    char writeBuffer[100] = {0};
    auto serial = std::make_unique<SampleSerial>("",writeBuffer,0);
    auto sensor = std::make_unique<SHT35Sensor>(0x03,serial.get(),sht35,0);
    auto actual = sensor->execute(Instruction(0,Bytes("\x02",1)));
    ASSERT_TRUE(actual);
}

本质上,我将代码移动到一个函数中,而不是std::shared_ptr<SHT35Sensor> prepare() { auto sht35 = SampleSHT35::create(); sht35->add(22.4,0); return std::make_shared<SHT35Sensor>(0x03,0); } TEST(SHT35Sensor,ValidInstruction) { auto sensor = prepare(); auto actual = sensor->execute(Instruction(0,1))); ASSERT_TRUE(actual); } ,而是使用unique_ptr,以便能够在创建它的函数调用者之间共享它。

但是,第二种变体在运行测试时导致分段错误,这意味着我对智能指针的理解是错误的。

我在做什么错了?

解决方法

在您的代码中serial.get()返回指针,但没有将其与unique_ptr分离,因此当prepare ends-unique_ptr删除SampleSerial实例并且shared_ptr包含指针时释放内存。您可以使用serial.release()或直接使用shared_ptr

以上答案假设SHT35Sensor将处理SampleSerial实例的生存期。但是,如果这不是真的,则将unique_ptr<SampleErial>传递给SHT35Sensor

return std::make_shared<SHT35Sensor>(0x03,std::move(serial),sht35,0);

您的SHT35Sensor应该接受std::unique_ptr<SampleErial>作为第二个参数-并使用构造函数初始化或再次std::move将其传递给类成员。

我更喜欢第二种解决方案,因为SHT35Sensor不会接受任何裸指针-很好。