我最近参加了一次工作面试,面试官给了我一个建模问题,涉及将不同的形状序列化到一个文件中。
任务是通过首先定义一个名为 Shape 的抽象类来实现圆形或矩形等形状,然后通过从基类 (Shape) 继承来实现各种形状(圆形、矩形......)。
每个形状的两个抽象方法是:read_to_file(应该从文件中读取形状)和 write_to_file 应该将形状写入文件。
所有这些都是通过在继承的形状中实现该虚函数来完成的(例如:对于圆,我写的是半径,对于正方形,我保存了正方形的边....)。
class Shape {
public:
string Shape_type;
virtual void write_into_file()=0;
virtual void read_into_files()=0;
Shape() {
}
virtual ~Shape() {
}};
class Square: public Shape {
public:
int size;
Square(int size) {
this->size = size;
}
void write_into_file() {
//write this Square into a file
}
void read_into_files() {
//read this Square into a file
}
};
这样做是为了看看我是否了解多态性。
但是,然后我被要求实现两个函数,它们采用 *shape
vector 并将其写入/读取到文件中。
写作部分很简单,大概是这样的:
for (Shape sh : Shapes) {
s.write_into_file();
}
至于阅读部分,我考虑过阅读文本中的第一个单词(我将可序列化文件实现为具有以下行的文本文件:Shape_type: Circle, Radius: 12; Shape_type:Square... .
,所以第一个字表示形状类型)。并将其保存为一个字符串,例如:
string shape_type;
shape_type="Circle";
然后我需要创建该特定形状的新实例,我想到了类似大开关的东西
<pre><code>
switch(shape_type):
{
case Circle: return new circle;
case Square: return new square
......
}
</pre></code>
然后面试官跟我说这个实现有问题
我认为这是一个事实,即我们将在未来添加的每个新形状我们也应该更新那个大开关。他试图引导我进入设计模式,我告诉他也许工厂设计模式会有所帮助,但我找不到摆脱该开关的方法。即使我将开关从函数移动到 FactoryClass
我仍然必须使用开关来检查形状的类型(根据我从文本文件中获得的字符串内容) .
我从文件中读取了一个字符串,表示形状的当前类型。我想做类似的事情:
string shape_type;
shape_type="Circle";
Shape s = new shape_type; //which will be like: Shape s = new Circle
但我不能用 c++ 做。
知道我应该做什么吗?
最佳答案
在您的工厂中,您可以映射 std::string
到 function<Shape*()>
.在启动时,您将向工厂注册工厂方法:
shapeFactory.add("circle", []{new Circle;});
shapeFactory.add("square", []{new Square;});
shapeFactory.add("triangle", []{new Triangle;});
在反序列化代码中,您读取类型的名称并从工厂获取其工厂方法:
std::string className = // read string from serialization stream
auto factory = shapeFactory.get(className);
Shape *shape = factory();
您现在已获得指向具体形状实例的指针,可用于反序列化对象。
编辑:根据要求添加了更多代码:
class ShapeFactory
{
private:
std::map<std::string, std::function<Shape*()> > m_Functions;
public:
void add(const std::string &name, std::function<Share*()> creator)
{
m_Functions.insert(name, creator)
}
std::function<Shape*()> get(const std::string &name) const
{
return m_Functions.at(name);
}
};
注意:我省略了错误检查。
关于c++ - 通过使用字符串调用新构造函数来创建新对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20615212/