编译代码时出现下一个错误。
Error C2280 'Square::Square(void)': attempting to reference a deleted function objectfactory.h 11
我有下一个对象工厂,对象:
template<class ID, class Base, class ... Args> class GenericObjectFactory {
private:
typedef Base* (*fInstantiator)(Args ...);
template<class Derived> static Base* instantiator(Args ... args) {
return new Derived(args ...);
}
std::map<ID, fInstantiator> classes;
public:
GenericObjectFactory() {}
template<class Derived> void add(ID id) {
classes[id] = &instantiator<Derived>;
}
fInstantiator get(ID id) {
return classes[id];
}
};
基类,例如:
class BaseFigure
{
private:
BaseFigure(const BaseFigure&);
int m_params_num;
public:
BaseFigure() : m_params_num(0) {};
virtual void draw(WDraw &drawer)=0;
virtual void boundingBox(WDraw &drawer) = 0;
virtual ~BaseFigure() {};
};
来自BaseFigure的派生类:
class Square :
public BaseFigure
{
private:
Point2d points[2];
public:
std::string type();
void draw(WDraw &drawer);
void boundingBox(WDraw &drawer);
~Square();
};
下面的方形实现:
void Square::draw(WDraw &drawer) {
Point2d cournerSecond(points[0].x(), points[1].y()), cournerFour(points[1].x(), points[0].y());
drawer.drawSegment(points[0], cournerSecond);
drawer.drawSegment(cournerSecond, points[1]);
drawer.drawSegment(points[1], cournerFour);
drawer.drawSegment(cournerFour, points[0]);
}
void Square::boundingBox(WDraw &drawer) {
this->boundingBox(drawer);
}
使用示例:
GenericObjectFactory<std::string , BaseFigure> figureFactory;
figureFactory.add<Square>("sq");
BaseFigure *sq = figureFactory.get("sq")();
我无法理解,错误在哪里? P.S添加了Point2D和WDraw。这个类的所有方法都有实现。
class Point2d
{
public:
Point2d(double xx, double yy);
virtual ~Point2d(void);
double x() const { return m_dX; }
double y() const { return m_dY; }
private:
double m_dX;
double m_dY;
};
class WDraw
{
public:
WDraw(void);
virtual ~WDraw(void);
virtual void drawSegment(const Point2d& p1, const Point2d& p2);
};
答案 0 :(得分:4)
这一行:
classes[id] = &instantiator<Derived>;
设置实例化器以使用此实例化函数:
static BaseFigure* instantiator() {
return new Square();
}
但Square
不是默认构造的,因为它的成员:
Point2d points[2];
不是默认构造的,因为它有一个用户声明的非默认构造函数:
Point2d(double xx, double yy);
因此错误。隐式声明的Point2d
默认构造函数被声明为已删除,这使得隐式声明的Square
默认构造函数也被声明为已删除。
要完成这项工作,您必须向Point2d
添加默认构造函数,或者允许通过Square
的构造函数将参数传递到{{1} }}。可能后者最有意义。
答案 1 :(得分:0)
修改使用示例:
GenericObjectFactory<std::string, BaseFigure, Point2d, double> figureFactory; //<===== A square could be constructed with top left point + width
figureFactory.add<Square>("sq");
BaseFigure *sq = figureFactory.get("sq")(Point2d(1.0,2.0), 2.0); //<===== Instatiate with right arguments
然后错误消息清楚地表明找不到合适的构造函数。让我们添加它:
Square(Point2d tl, double w)
{
points[0] = tl;
points[1] = Point2d(tl.x()+w, tl.y()+w);
}
遗憾的是,数组不能在mem-initializer中初始化,因此Point2d也需要一个默认的构造函数。所以添加它,它编译好!