问题描述
我正在尝试掌握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
不会接受任何裸指针-很好。