经过大量研究,我仍然不明白如何使用智能指针处理抽象类集合。
这是我得到的错误:
error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Shape; _Dp = std::default_delete<Shape>]'
base_ptr s = shapes.front();
error: no matching function for call to 'std::unique_ptr<Shape>::unique_ptr(Shape&)'
shapes.push(base_ptr(b));
通过编译最少的代码来复制错误 (code online avaiable)。
#include <queue>
#include <memory>
class Shape {
public:
virtual int getPerimeter() =0;
};
typedef std::unique_ptr<Shape> base_ptr;
class Circle : public Shape {
public:
virtual int getPerimeter() { return 1; };
};
class Square : public Shape {
public:
virtual int getPerimeter() { return 0; };
};
class ShapeManager {
public:
ShapeManager();
void useShape() {
if(shapes.empty())
throw "Work stack is empty.";
base_ptr s = shapes.front();
s->getPerimeter();
shapes.pop();
}
void submitShape(Shape &b) {
shapes.push(base_ptr(b));
}
private:
std::queue<base_ptr> shapes;
};
int main(int argc, char **argv) {
ShapeManager s();
Circle c;
s.submitShape(c);
s.useShape();
return 1;
}
如果我声明 queue
就可以了作为queue<Shape*>
但我不想处理指针 - 意思是 *。
编辑,此代码编译。谢谢大家。 This article Guillaume Racicot 建议有助于更清楚地了解情况。
#include <queue>
#include <memory>
class Shape {
public:
virtual int getPerimeter() =0;
};
typedef std::unique_ptr<Shape> base_ptr;
class Circle : public Shape {
public:
Circle() {};
virtual int getPerimeter() { return 1; };
};
class Square : public Shape {
public:
virtual int getPerimeter() { return 0; };
};
class ShapeManager {
public:
ShapeManager();
void useShape() {
if(shapes.empty())
throw "Work stack is empty.";
base_ptr s = std::move(shapes.front());
s->getPerimeter();
shapes.pop();
}
void submitShape(base_ptr b) {
shapes.push(std::move(b));
}
private:
std::queue<base_ptr> shapes;
};
int main(int argc, char **argv) {
ShapeManager s;
base_ptr c = std::make_unique<Circle>();
s.submitShape(std::move(c));
s.useShape();
return 1;
}
最佳答案
容器会让人分心。问题是 unique_ptr
是不可复制的;如果是,它就不是唯一的。所以您可能需要添加对 std::move
的调用:
base_ptr s = std::move(shapes.front());
这意味着与原始代码可能打算做的事情不同;它从容器中移除对象。如果这不是您想要的,那么 std::move
就不是正确的答案,并且 unique_ptr
可能不是正确的机制。
关于c++ - 管理标准容器中的抽象类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44949317/