如何将智能指针从函数传递给调用者?
How do I pass a smart pointer from a function to the caller?
我正在尝试掌握 C++ 中智能指针的概念。我有以下代码(使用 GoogleTest 的单元测试):
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, 0, Bytes("\x02", 1)));
ASSERT_TRUE(actual);
}
我想隔离测试的前五行,以便重新使用它们。我认为这样做就足够了(尤其是正确的):
std::shared_ptr<SHT35Sensor> prepare() {
auto sht35 = SampleSHT35::create();
sht35->add(22.4, 56.5);
char writeBuffer[100] = {0};
auto serial = std::make_unique<SampleSerial>("", writeBuffer, 0);
return std::make_shared<SHT35Sensor>(0x03, serial.get(), sht35, 0);
}
TEST(SHT35Sensor, ValidInstruction) {
auto sensor = prepare();
auto actual = sensor->execute(Instruction(0, 0, Bytes("\x02", 1)));
ASSERT_TRUE(actual);
}
本质上,我将代码移动到一个函数中,而不是 unique_ptr
,我使用 shared_ptr
以便能够在创建它的函数和调用者之间共享它。
然而,第二种变体在运行测试时导致段错误,这意味着我对智能指针的理解是错误的。
我做错了什么?
在您的代码中 serial.get()
returns 指针,但不会将其与 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>
作为第二个参数 - 并使用构造函数初始化或再次将其传递给 class 成员 std::move
.
我更喜欢第二种解决方案,因为 SHT35Sensor
不接受裸指针 - 这很好。
我正在尝试掌握 C++ 中智能指针的概念。我有以下代码(使用 GoogleTest 的单元测试):
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, 0, Bytes("\x02", 1)));
ASSERT_TRUE(actual);
}
我想隔离测试的前五行,以便重新使用它们。我认为这样做就足够了(尤其是正确的):
std::shared_ptr<SHT35Sensor> prepare() {
auto sht35 = SampleSHT35::create();
sht35->add(22.4, 56.5);
char writeBuffer[100] = {0};
auto serial = std::make_unique<SampleSerial>("", writeBuffer, 0);
return std::make_shared<SHT35Sensor>(0x03, serial.get(), sht35, 0);
}
TEST(SHT35Sensor, ValidInstruction) {
auto sensor = prepare();
auto actual = sensor->execute(Instruction(0, 0, Bytes("\x02", 1)));
ASSERT_TRUE(actual);
}
本质上,我将代码移动到一个函数中,而不是 unique_ptr
,我使用 shared_ptr
以便能够在创建它的函数和调用者之间共享它。
然而,第二种变体在运行测试时导致段错误,这意味着我对智能指针的理解是错误的。
我做错了什么?
在您的代码中 serial.get()
returns 指针,但不会将其与 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>
作为第二个参数 - 并使用构造函数初始化或再次将其传递给 class 成员 std::move
.
我更喜欢第二种解决方案,因为 SHT35Sensor
不接受裸指针 - 这很好。