将引用参数传递给采用 unique_ptr 的通用引用的函数
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
,有效地复制了现有对象。当然,它不能那样做,因为 class 是抽象的。
除非你有办法保证传递给 MyUserClass
的引用是动态(“堆”)变量(并且它的指针不被拥有等),否则你不能只捕获它的指针在 unique_ptr
中,然后在 doSomethingElse
之后释放它。即使这是有保证的,据您所知,doSomethingElse
仍然可以尝试删除指针本身(除非您确切知道它的作用)。当您通过右值引用传递它时,对象在 doSomethingElse
returns.
之后可能无效
这意味着您必须制作该对象的副本。但是,您不能制作普通副本。您需要复制整个非抽象的底层对象。
如果允许您更改 classes 的签名,添加一个虚拟 clone
方法就可以了。
如果不是,一个不太糟糕的解决方法可能是(你需要事先知道所有继承 MyAbstractClass
的类型)switch(typeid(mac))
和 dynamic_cast
.
我有两个无法更改签名的函数。第一个采用对对象的引用,而第二个采用对同一对象的唯一指针的通用引用。我不确定如何将第一个参数传递给第二个参数。
我尝试通过引用的地址传递一个新的唯一 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
,有效地复制了现有对象。当然,它不能那样做,因为 class 是抽象的。
除非你有办法保证传递给 MyUserClass
的引用是动态(“堆”)变量(并且它的指针不被拥有等),否则你不能只捕获它的指针在 unique_ptr
中,然后在 doSomethingElse
之后释放它。即使这是有保证的,据您所知,doSomethingElse
仍然可以尝试删除指针本身(除非您确切知道它的作用)。当您通过右值引用传递它时,对象在 doSomethingElse
returns.
这意味着您必须制作该对象的副本。但是,您不能制作普通副本。您需要复制整个非抽象的底层对象。
如果允许您更改 classes 的签名,添加一个虚拟 clone
方法就可以了。
如果不是,一个不太糟糕的解决方法可能是(你需要事先知道所有继承 MyAbstractClass
的类型)switch(typeid(mac))
和 dynamic_cast
.