考虑以下代码:
#include <stdio.h>
// =============================
class Shape{
public:
virtual ~Shape(){};
virtual void process() = 0;
};
class Triangle : public Shape{
public:
virtual void process() override {
printf("BBB\n");
}
};
// =============================
/* option 1 */
class TriangleProducer{
public:
Triangle factory(){
return Triangle {};
}
};
/* option 2 */
class PtrShapeProducer{
public:
Shape *factory(){
return new Triangle {};
}
};
/* option 3 */
class PimplShape : public Shape{
Shape *sh;
public:
PimplShape(Shape *sh) : sh(sh){
}
virtual ~PimplShape() override{
delete sh;
}
virtual void process() override {
sh->process();
}
};
class PimplShapeProducer{
public:
PimplShape factory(){
return new Triangle {};
}
};
// =============================
int main(){
TriangleProducer f1;
Triangle tri = f1.factory();
tri.process();
PtrShapeProducer f2;
Shape & sh = *f2.factory();
sh.process();
delete & sh;
PtrShapeProducer f3;
PimplShape psh = f3.factory();
psh.process();
return 0;
}
OPTION 1
不错,但是并没有真正实现多态。返回类型是已知的,您必须匹配它。可以加一个auto
代替Triangle
,但这除了更容易重构之外不会改变任何东西。
OPTION 2
Java 和 PHP 就是这样做的。但我知道“原始”指针在 C++ 中是不可取的。可以加一个std::unique_ptr
,但这并没有改变任何东西,除了缺失delete
陈述。
OPTION 3
这是前段时间有人在这里提出的建议 - 效果很好,没有“原始”指针,没有删除。但代码太多,而且太复杂——看起来很奇特,但不是正确的方法。
OPTION 4(此处未实现)
使用 const 引用 - 然而它们是 const 并且它不会改变“工厂”返回类型。我认为,这更像是变异,而不是真实的选择。
我还缺少其他选择吗?
另外,最好的选择是什么?
我认为最惯用语现代 C++ 方法是您顺便提到但忽略的方法。返回一个std::unique_ptr<Shape>
.
它是安全的,清楚地表达所有权,支持多态性并且不需要太多代码。
class ShapeFactory {
public:
std::unique_ptr<Shape> create(){
return std::make_unique<Triangle>();
}
};
但我不想声称这是“最好”的方法。
Your PimplShape
选项3实际上与a非常相似unique_ptr
只是不太通用或经过测试。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)