删除returnShapeType
创建的对象的方式和位置?
这是一个工厂方法演示程序。
请出示代码。
class Shape
{
public:
Shape() {}
virtual void print() {std::cout << "\nFrom shape print";}
};
class Triangle: public Shape
{
public:
Triangle(){}
virtual void print() {std::cout << "\nFrom triangle print";}
};
class Rectangle: public Shape
{
public:
Rectangle(){}
virtual void print() {std::cout << "\nFrom rect print";}
};
class CreateShapeObject
{
public:
CreateShapeObject() {}
Shape *returnShapeType( std::string arg )
{
if (arg == "Triangle")
return new Triangle;
else if (arg == "Rectangle")
return new Rectangle;
}
};
////////////
class EndDeveloper
{
public:
CreateShapeObject obj;
EndDeveloper()
{
Shape *p = obj.returnShapeType("Triangle");
p->print();
Shape *q = obj.returnShapeType("Rectangle");
q->print();
}
};
答案 0 :(得分:6)
使用原始指针容易出错。使用unique_ptr
:
std::unique_ptr<Shape> returnShapeType(const std::string& arg)
{
if (arg == "Triangle")
return std::make_unique<Triangle>();
else if (arg == "Rectangle")
return std::make_unique<Rectangle>();
throw std::invalid_argument("Invalid shape");
}
您可以使用auto
:
auto shape = obj.returnShapeType("Triangle");
unique_ptr
也可以隐式转换为shared_ptr
:
std::shared_ptr<Shape> shape = obj.returnShapeType("Triangle");
答案 1 :(得分:2)
通过工厂处理new
的任何使用,就像处理new
的任何其他用途一样。
即使用new
(通过工厂或非工厂)的代码/类也负责执行delete
。
答案 2 :(得分:2)
您必须在设计中建立所有权原则。
在您发布的代码中,CreateShapeObject
不会保留指向所构造对象的指针。它只返回指向构造对象的指针。这意味着调用函数/类必须拥有该对象的所有权。他们应该负责删除它,除非他们将所有权传递给另一个函数/类,在这种情况下,其他函数/类应该负责删除它。
如果你想让CreateShapeObject
负责删除它构造的对象,你必须更新它以跟踪它构造的对象。此时,您可能希望更改类的名称以反映双重责任。 ShapeObjectManager
的某些内容会更有意义。