c++ - 使用模板向上转换 unique_ptr
问题描述
考虑以下简单代码:
#include <memory>
template<typename T>
struct Foo
{
virtual T & foo() = 0;
};
struct Bar : public Foo<int>
{
int x;
virtual int & foo() override
{
return x;
}
};
void baz(std::unique_ptr<Foo<int>>)
{
}
int main()
{
auto up = std::make_unique<Bar>();
baz(up);
return 0;
}
它不会编译报告此错误:
prog.cc:27:9: error: could not convert 'up' from 'unique_ptr<Bar,default_delete<Bar>>' to 'unique_ptr<Foo<int>,default_delete<Foo<int>>>'
27 | baz(up);
| ^~
| |
| unique_ptr<Bar,default_delete<Bar>>
我想知道如何解决这个问题。share_ptr
似乎有适当的铸造方法来解决这个问题,而似乎unique_ptr
没有其他选择。
解决方案
首先,您正在baz
按 value接受论点,这意味着复制a std::unique_ptr
and... 这是不可能的(或std::move
ing 它,但我怀疑这就是您想要的)。
其次,std::unique_ptr
不转换,因为那需要复制。
解决方法是什么?
你可以做:
std::unique_ptr<Foo<int>> up = std::make_unique<Bar>();
代替:
auto up = std::make_unique<Bar>();
并baz
通过引用获取参数:
void baz(std::unique_ptr<Foo<int>>&) { ... }
首先是保存一个unique_ptr
to 派生在一个unique_ptr
to 基础中。auto
不能这样做,除非你使用演员表。
第二件事是,如前所述,不要复制.unique_ptr
更重要的是,您的代码表现出未定义的行为,因为您使用基类指针删除了派生类对象。这需要virtual
基类中的析构函数。
推荐阅读
- postman - 使用 Postman 调用带有 multipart/form-data 的 Spring Boot 2 REST 服务会导致 EOFException
- pyspark - PySpark 可以处理 os.walk 以遍历子文件夹吗?
- amazon-web-services - ElasticSearch API 请求未得到响应
- security - Linux 4.4 嵌入式实时系统上的 SHA256
- python - 在for循环中用python中的索引切片矩阵
- rest - 如何从我的 api 获取多个页面的所有数据?
- configuration - 如何在 Symfony 3.4 中配置来自另一个包的包?
- arrays - 尝试在 NodeJS 中使用 Jimp (Express) 从 Multer 上传多个图像时出现问题
- python - Keras 图像分类:显示的准确度很高,但测试图像上的准确度很低
- python - 用重复行替换原始行,然后删除重复项