c++ - 如何将智能指针从函数传递给调用者?
问题描述
我试图掌握 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()
中返回指针,但不会将其与 分离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
- 这很好。
推荐阅读
- mysql - 在使用连接和大小写编写复杂的 sql 查询时需要帮助
- python - 如何从本地窗口与代码调试远程 python 代码
- javascript - 使用 Axios 向服务器发出 http 请求时出现问题
- flutter - pub 失败:因为 flutter_google_places >=0.2.5 取决于 rxdart ^0.24.0 上 rxdart ^0.23.1,
- ag-grid - 如何让 ag-grid 表将字符串数组分解为同一列中的多行
- google-bigquery - 无法将 _TABLE_SUFFIX 与嵌套列一起使用
- javascript - 将 React 样式转换为 CSS
- python - discord.py embed 将列表打印为字符串,而不是单独的条目
- python - 如何在 python 中使用 Uvicorn 运行服务器时进行加密(从 http 到 https)
- python - 如何在我的 scikit 管道中正确应用标签编码器?