我目前有以下代码(不工作):
#include <iostream>
#include <vector>
class Circle;
class Rectangle;
class Shape {
private:
Shape() {};
public:
virtual ~Shape() {};
friend class Circle;
friend class Rectangle;
};
class Creator {
public:
virtual ~Creator() {};
virtual Shape* create() = 0;
virtual bool equals(Shape& s) { return false; };
};
class Circle : public Shape {
private:
Circle() : Shape() {};
public:
class CircleCreator : public Creator {
public:
virtual Shape* create() { return new Circle(); };
virtual bool equals(Shape& other_shape) { return false; };
};
};
class Rectangle : public Shape {
private:
Rectangle() : Shape() {};
public:
class RectangleCreator : public Creator {
public:
virtual Shape* create() { return new Rectangle(); };
virtual bool equals(Shape& other_shape) { return false; };
};
};
int main() {
/* First step, build the list */
std::vector<Shape*> shapeList;
std::vector<Shape*>::iterator it;
Rectangle::RectangleCreator rc;
Circle::CircleCreator cc;
Shape* s = cc.create();
Shape* s1 = rc.create();
shapeList.push_back(s);
shapeList.push_back(s1);
/* Second step: check if we've got a shape starting from a creator */
for (it = shapeList.begin(); it != shapeList.end(); ++it) {
if (rc.equals(**it)) {
std::cout << "same shape" << std::endl;
}
}
return 0;
}
我的目标是使用工厂模式并避免创建新对象(如果列表中已有该对象)。我尝试使用双分派(dispatch)模式,但在这种情况下应用起来并不容易。我该怎么办?
编辑:由于代码在“关键”路径中使用,我想避免像 dynamic_cast 等 RTTI。
最佳答案
也许像这样的事情可以使用成员变量来完成
#include <iostream>
#include <vector>
enum
{
CIRCLE,
RECTANGLE
};
class Circle;
class Rectangle;
class Shape {
private:
Shape() {};
public:
unsigned shapeType;
virtual ~Shape() {};
friend class Circle;
friend class Rectangle;
};
class Creator {
public:
unsigned shapeType;
virtual ~Creator() {};
virtual Shape* create() = 0;
bool equals(Shape& s) { return (this->shapeType == s.shapeType); };
};
class Circle : public Shape {
private:
Circle() : Shape() {shapeType=CIRCLE;};
public:
class CircleCreator : public Creator {
public:
CircleCreator() {shapeType=CIRCLE;};
virtual Shape* create() { return new Circle(); };
};
};
class Rectangle : public Shape {
private:
Rectangle() : Shape() {shapeType=RECTANGLE;};
public:
class RectangleCreator : public Creator {
public:
RectangleCreator() {shapeType=RECTANGLE;};
virtual Shape* create() { return new Rectangle(); };
};
};
int main() {
/* First step, build the list */
std::vector<Shape*> shapeList;
std::vector<Shape*>::iterator it;
Rectangle::RectangleCreator rc;
Circle::CircleCreator cc;
Shape* s = cc.create();
Shape* s1 = rc.create();
shapeList.push_back(s);
shapeList.push_back(s1);
/* Second step: check if we've got a shape starting from a creator */
for (it = shapeList.begin(); it != shapeList.end(); ++it) {
if (rc.equals(**it)) {
std::cout << "same shape" << std::endl;
}
}
return 0;
}
或者这个——使用虚函数返回类型
#include <iostream>
#include <vector>
enum
{
CIRCLE,
RECTANGLE,
UNKNOWN
};
class Circle;
class Rectangle;
class Shape {
private:
Shape() {};
public:
virtual ~Shape() {};
friend class Circle;
friend class Rectangle;
virtual unsigned iAmA(){return UNKNOWN;};
};
class Creator {
public:
virtual ~Creator() {};
virtual Shape* create() = 0;
virtual bool equals(Shape& s) { return false; };
};
class Circle : public Shape {
private:
Circle() : Shape() {};
virtual unsigned iAmA(){return CIRCLE;};
public:
class CircleCreator : public Creator {
public:
CircleCreator() {};
virtual Shape* create() { return new Circle(); };
virtual bool equals(Shape& other_shape) { return (CIRCLE == other_shape.iAmA()); };
};
};
class Rectangle : public Shape {
private:
Rectangle() : Shape() {};
virtual unsigned iAmA(){return RECTANGLE;};
public:
class RectangleCreator : public Creator {
public:
RectangleCreator() {};
virtual Shape* create() { return new Rectangle(); };
virtual bool equals(Shape& other_shape) { return (RECTANGLE == other_shape.iAmA()); };
};
};
int main() {
/* First step, build the list */
std::vector<Shape*> shapeList;
std::vector<Shape*>::iterator it;
Rectangle::RectangleCreator rc;
Circle::CircleCreator cc;
Shape* s = cc.create();
Shape* s1 = rc.create();
shapeList.push_back(s);
shapeList.push_back(s1);
/* Second step: check if we've got a shape starting from a creator */
for (it = shapeList.begin(); it != shapeList.end(); ++it) {
if (rc.equals(**it)) {
std::cout << "same shape" << std::endl;
}
}
return 0;
}
关于c++ - 双分派(dispatch)和工厂模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28912568/