[英]passing reference argument to function taking universal reference of unique_ptr
我有两个无法更改其签名的函数。 第一个引用一个对象,而第二个引用一个指向同一对象的唯一指针的通用引用。 我不确定如何将第一个参数传递给第二个参数。
我已经尝试通过使用引用的地址传递一个新的唯一 ptr,但是由于引用是抽象的,编译器会抱怨未实现的方法。
下面是一个例子:
// Example program
#include <iostream>
#include <memory>
class MyAbstractClass {
public:
virtual void doSomething() = 0;
};
class MyConcreteClass : public MyAbstractClass {
public:
void doSomething() override {
std::cout << "Hello I do something" << std::endl;
}
};
class MyUserClass {
public:
MyUserClass(MyAbstractClass& mac){
// the line below doesn't work !!
doSomethingElse(std::make_unique<MyAbstractClass>(&mac));
}
void doSomethingElse(std::unique_ptr<MyAbstractClass>&& mac){
mac->doSomething();
}
};
int main() {
MyConcreteClass mcc;
MyUserClass muc(mcc);
}
您的编译器会抱怨,因为make_unique
在您尝试实例化的类型上调用了new
,从而有效地复制了现有对象。 当然,它不能这样做,因为该类是抽象的。
除非你有办法保证传递给MyUserClass
的引用是一个动态(“堆”)变量(并且它的指针不被拥有等),你不能只在unique_ptr
捕获它的指针,然后在doSomethingElse
之后释放它。 即使这是有保证的,就您所知, doSomethingElse
仍然可以尝试删除指针本身(除非您确切地知道它的作用)。 当您通过右值引用传递它时,对象在doSomethingElse
返回后可能不再有效。
这意味着您必须制作对象的副本。 但是,您无法制作普通副本。 您需要复制整个、非抽象的底层对象。
如果您被允许更改类的签名,那么添加一个虚拟clone
方法就可以了。
如果没有,一个不是绝对可怕的解决方法可能是(你需要事先知道所有继承MyAbstractClass
的类型) switch(typeid(mac))
和dynamic_cast
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.