如何将智能指针二维数组传入原生指针参数函数且不修改参数?
如何用智能指针数组适配接收原生指针二维数组的函数?
我需要一个存储接口类指针的静态二维数组,用原生指针Base* rawr[5][5]能正常运行,但想改用智能指针,同时不能修改Foo的参数类型,只能传原生指针给它,怎么让代码正常跑?
原代码及报错如下:
class Base {}; class Child : public Base {}; void Foo(Base* array[5][5]) { // Stuff } void OtherFoo(std::unique_ptr<Base> array[5][5]) { // Stuff } int main() { std::unique_ptr<Base> rawr[5][5]; // 报错:参数类型 "std::unique_ptr<Base, std::default_delete<Base>> (*)[5]" 与 "Base *(*)[5]" 不兼容 Foo(rawr); // 报错:无法从 "std::unique_ptr<Base, std::default_delete<Base>>" 转换为 "Base *(*)[5]" Foo(rawr[5][5]); // 报错:表达式必须具有类类型,但它的类型是 "std::unique_ptr<Base, std::default_delete<Base>> (*)[5]" Foo(rawr.get()); // 报错:表达式必须具有指向类的指针类型,但它的类型是 "std::unique_ptr<Base, std::default_delete<Base>> (*)[5]" Foo(rawr->get()); // 这个可以正常运行 OtherFoo(rawr); }
解决方案
核心问题是std::unique_ptr<Base>的二维数组和Base*的二维数组类型完全不兼容,没有隐式转换规则,必须手动提取原生指针构造临时数组:
int main() { std::unique_ptr<Base> rawr[5][5]; // 构造一个原生指针的临时二维数组 Base* temp_array[5][5]; for (int i = 0; i < 5; ++i) { for (int j = 0; j < 5; ++j) { // 提取每个智能指针持有的原生指针 temp_array[i][j] = rawr[i][j].get(); } } Foo(temp_array); // 现在可以正常传参 OtherFoo(rawr); // 原有调用不受影响 }
为什么之前的写法都不行?
- 直接传
rawr:数组名退化为std::unique_ptr<Base>(*)[5]类型的指针,和Foo需要的Base*(*)[5]类型不匹配,C++不支持这种跨类型的隐式转换 rawr[5][5]是单个智能指针对象,而Foo要求的是二维数组的指针,类型维度完全不符rawr.get()/rawr->get():数组退化成指针后是指向数组的指针,不是智能指针对象,自然不能调用智能指针的成员函数
注意事项
- 临时数组里的指针只是智能指针的副本,所有权仍在
rawr的智能指针手中,只要rawr的智能指针未释放,临时数组的指针就有效 - 如果Foo内部需要长期持有这些指针,要确保
rawr的智能指针生命周期覆盖Foo的使用周期;或者考虑改用std::shared_ptr(同样需要提取原生指针传入Foo)
内容的提问来源于stack exchange,提问作者segragationofthenation
相关产品推荐
相关产品推荐

