【发布时间】:2017-12-05 18:25:54
【问题描述】:
我对 C++(来自 Java/PHP)相当陌生。基本上,我需要创建一个容器类,它将保存对虚拟类实例(基类)的唯一/共享指针的引用。我无法编译这段代码(我使用的是 MSVC 2015)。
编译错误是:
error C2280: 'std::unique_ptr<Base,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function
这是一个重现问题的示例应用程序:
#include <iostream>
#include <memory>
class Base {
public:
virtual void foo() const = 0;
virtual void bar() const = 0;
};
class Derived : public Base {
public:
void foo() const override {
std::cout << "foo" << std::endl;
};
void bar() const override{
std::cout << "bar" << std::endl;
};
};
class ContainerUnique {
public:
ContainerUnique() {
ptr = nullptr;
}
void assignPtr(const Base &instance) {
auto ptr = std::make_unique<Base>(instance);
ptr.swap(ptr);
};
std::unique_ptr<Base> getPtr() {
return ptr;
};
private:
std::unique_ptr<Base> ptr;
};
class ContainerShared {
public:
ContainerShared() {
ptr = nullptr;
}
void assignPtr(const Base &instance) {
auto ptr = std::make_shared<Base>(instance);
ptr.swap(ptr);
};
std::shared_ptr<Base> getPtr() {
return ptr;
};
private:
std::shared_ptr<Base> ptr;
};
int main() {
Derived derived1 = Derived();
Derived derived2 = Derived();
ContainerUnique cu = ContainerUnique();
ContainerShared cs = ContainerShared();
cu.assignPtr(derived1);
cs.assignPtr(derived2);
std::unique_ptr<Base> uptr = cu.getPtr();
std::shared_ptr<Base> sptr = cs.getPtr();
return 0;
}
请指教
【问题讨论】:
-
std::unique_ptr<Base> getPtr()返回一个副本。你不能复制unique_ptr。我不确定您要达到什么语义。getPtr是否应该共享所有权?如果是这样,您不能使用unique_ptr。如果不是,请不要返回智能指针。 -
与错误无关:在这种情况下,您不需要覆盖的默认构造函数,也不应该使用
ptr.swap(或同名的临时变量)。只需ptr = std::make_unique<Base>(instance);就足够了 -
@UnholySheep。我刚试了一下,编译器抛出
error C2259: 'Base': cannot instantiate abstract class -
assignPtr()接收到const Base&引用并尝试复制构造一个新的Base对象,而不是Derived,因此出现错误。此外,assignPtr()将新的std::unique_ptr分配给局部变量ptr,然后将swap分配给它本身,而不是类的ptr成员。您需要更改ContainerUnique::assignPtr()以将std::unique_ptr<Base>作为输入并将std::move()更改为类的ptr成员,并更改ContainerShared::assignPtr()以将std::shared_ptr<Base>作为输入并将其分配给类的ptr成员。 -
@RemyLebeau:但是您会尝试(并且失败)获得具有自动生命周期的变量的
unique_ptr所有权。整个设计是一个 X-Y 问题,有很多破损,有很多不同的方向要让它合法,没有任何描述预期用途的东西,所以没有办法在它们之间做出选择。
标签: c++ c++14 virtual shared-ptr unique-ptr