将 unique_ptr<Derived>& 传递给接受 unique_ptr<Base>& 的函数
Passing unique_ptr<Derived>& to a function accepting unique_ptr<Base>&
我需要通过引用一个函数来传递一个指向派生 class 的唯一指针,该函数接受对基 class 的唯一指针的引用,如下所示:
#include <memory>
using namespace std;
class Base {};
class Derived : public Base {};
void foo(std::unique_ptr<Base>& d){}
int main()
{
unique_ptr<Derived> b = make_unique<Derived>();
foo(b);
}
为什么这段代码不起作用?我查看了其他帖子,如this one,答案似乎是"because C++ wants the types to match exactly",但这是为什么呢?我可能会造成什么危险情况?
如果我改为这样做,它会编译:
void foo(unique_ptr<Base>&& d){}
foo(move(b));
这是一个合理的方法吗?
从 Derived 到 Base 的简单 static_cast,带有适当的释放调用(将资源的所有权转移到新创建的指针)应该可以正常工作。
int main()
{
unique_ptr<Derived> b = make_unique<Derived>();
std::unique_ptr<Base> basePointer(static_cast<Base*>(b.release()));
foo(basePointer);
}
What dangerous situation am I potentially creating?
想象一下 foo 的以下实现:
void foo(std::unique_ptr<Base>& d){
d.reset(new Base);
}
您现在有一个 std::unique_ptr<Derived>
指向一个非 Derived
类型的对象,并且编译器无法给您任何类型的警告。
如评论中所述,您问题的正确解决方案是按值获取 std::unique_ptr<Base>
,并将其移动到调用站点。
void foo(std::unique_ptr<Base> d) {
// move d to your list
}
int main() {
unique_ptr<Derived> b = make_unique<Derived>();
foo(std::move(b));
}
我需要通过引用一个函数来传递一个指向派生 class 的唯一指针,该函数接受对基 class 的唯一指针的引用,如下所示:
#include <memory>
using namespace std;
class Base {};
class Derived : public Base {};
void foo(std::unique_ptr<Base>& d){}
int main()
{
unique_ptr<Derived> b = make_unique<Derived>();
foo(b);
}
为什么这段代码不起作用?我查看了其他帖子,如this one,答案似乎是"because C++ wants the types to match exactly",但这是为什么呢?我可能会造成什么危险情况?
如果我改为这样做,它会编译:
void foo(unique_ptr<Base>&& d){} foo(move(b));
这是一个合理的方法吗?
从 Derived 到 Base 的简单 static_cast,带有适当的释放调用(将资源的所有权转移到新创建的指针)应该可以正常工作。
int main()
{
unique_ptr<Derived> b = make_unique<Derived>();
std::unique_ptr<Base> basePointer(static_cast<Base*>(b.release()));
foo(basePointer);
}
What dangerous situation am I potentially creating?
想象一下 foo 的以下实现:
void foo(std::unique_ptr<Base>& d){
d.reset(new Base);
}
您现在有一个 std::unique_ptr<Derived>
指向一个非 Derived
类型的对象,并且编译器无法给您任何类型的警告。
如评论中所述,您问题的正确解决方案是按值获取 std::unique_ptr<Base>
,并将其移动到调用站点。
void foo(std::unique_ptr<Base> d) {
// move d to your list
}
int main() {
unique_ptr<Derived> b = make_unique<Derived>();
foo(std::move(b));
}