为什么以及如何使用原型设计模式
Why and how should I use prototype design pattern
我正在学习设计模式并尝试自己实现它们。对于大多数设计模式,我可以理解那里的使用和实现,但我对原型模式感到困惑。这是我实现它的方法。
船.h
class IShipPrototype
{
public:
virtual IShipPrototype* clone() = 0;
IShipPrototype(const std::string sName, float w = 10, float h = 10, float s = 10) : shipName{ sName }, width{ w }, height{ h }, speed{ s } {};
IShipPrototype(const IShipPrototype &that)
{
shipName = that.shipName;
width = that.width;
height = that.height;
speed = that.speed;
}
void Print()
{
std::cout << "-----------------------n";
std::cout << "tShip Infotn" <<
"Name:tt" << shipName << "n" <<
"Width:tt" << width << "n" <<
"Height:tt" << height << "n" <<
"Speed:tt" << speed << std::endl;
}
void SetShipName(const std::string &newShipName) { shipName = newShipName; }
void SetShipHeight(float NewHeight) { height = NewHeight; }
void SetShipWidth(float NewWidth) { width = NewWidth; }
void SetShipSpeed(float NewSpeed) { speed = NewSpeed; }
private:
std::string shipName;
float width = 0, height = 0, speed = 0;
};
class Ship : public IShipPrototype
{
public:
Ship(const std::string& sName, float w, float h, float s) : IShipPrototype(sName, w, h, s) {}
Ship(const Ship &ship) : IShipPrototype(ship) {}
IShipPrototype* clone() override
{
return new Ship(*this);
}
};
class ShipFactory
{
public:
ShipFactory()
{
ships[0] = new Ship("titanic", 12, 43, 47);
ships[1] = new Ship("Black pearl", 15, 73, 24);
ships[2] = new Ship("Man O War", 32, 46, 14);
ships[3] = new Ship("Rose Marry", 24, 53, 52);
}
IShipPrototype* CreateCloneShip(int idx)
{
return ships[idx]->clone();
}
private:
std::map<int, IShipPrototype*> ships;
};
主.cpp
int main()
{
ShipFactory *factory = new ShipFactory();
IShipPrototype* titanicClone = factory->CreateCloneShip(0);
IShipPrototype* blackPearlClone = factory->CreateCloneShip(1);
IShipPrototype* manOwarClone = factory->CreateCloneShip(2);
IShipPrototype* roseMarry = factory->CreateCloneShip(3);
titanicClone->SetShipName("titanicClone");
titanicClone->SetShipHeight(100);
titanicClone->Print();
blackPearlClone->SetShipName("blackPearlClone");
blackPearlClone->SetShipSpeed(10);
blackPearlClone->Print();
manOwarClone->SetShipName("manOwarClone");
manOwarClone->SetShipWidth(40);
manOwarClone->Print();
roseMarry->SetShipName("roseMarry");
roseMarry->SetShipSpeed(130);
roseMarry->Print();
getchar();
return EXIT_SUCCESS;
}
让我感到困惑的部分是克隆函数返回接口的指针,这意味着我无法将克隆存储在不同的飞船对象中,例如。Ship* ship = factory->CreateCloneShip(0);
.
我认为这种设计模式背后的想法是创建现有对象的克隆,然后更改它的一些细节。
是我的实现不正确还是我错过了什么?
原型模式允许我们通过调用虚拟成员函数(通常在代码中称为clone(),
(多态地创建对象的副本。
让我感到困惑的部分是克隆函数返回接口的指针,这意味着我无法将克隆存储在不同的飞船对象中
通常,重写函数的类型必须与它所覆盖的虚拟函数的类型完全相同。但是,如果要重写的虚函数返回(原始(指针或引用,则对于允许重写函数返回的类型,存在一些约束放宽。
如果是这种情况,重写函数的返回类型可能是指向被重写函数返回指针的类类型的派生类的指针或引用。这称为方法的协变返回类型。
现在,考虑到这一点,并专注于IShipPrototype::clone()
虚拟成员功能。它返回一个IShipPrototype*
:
class IShipPrototype {
public:
virtual IShipPrototype* clone() = 0; // returns IShipPrototype*
// ...
};
由于IShipPrototype
是Ship
的公共基础,覆盖Ship::clone()
可以返回Ship*
而不是IShipPrototype*
:
class Ship: public IShipPrototype {
public:
Ship* clone() override; // returns Ship*
// ...
};
这样,如果你有一个Ship
对象,并且你直接在它上面调用clone()
,你会得到一个Ship*
,而不是一个IShipPrototype*
——尽管Ship*
确实隐式转换为IShipPrototype*
IShipPrototype
因为它是Ship
的公共基类。 这里的IShipPrototype
和Ship
被称为协变类型。
请注意,如果通过IShipPrototype
接口调用clone()
,则返回指针指向的类型的静态类型为IShipPrototype*
。但是,如果在Ship
实例上调用动态类型,则将Ship
动态类型。
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 资源管理设计模式
- 用于在回调中调用解析器的设计模式
- 设计帮助 - 为不同类型的消息处理通用接口的设计模式
- 在这种情况下我应该使用哪种设计模式
- C++中物体改变识别的设计模式?
- 确保所有构造函数调用相同的函数 c++ 设计模式
- 需要实例化不同类/对象并在启动时确定的硬件插槽的设计模式
- 设计模式,以避免不必要地添加抽象函数以适应新功能
- 工厂设计模式优化
- 使用C++模板的数据映射器设计模式
- 为什么以及如何使用原型设计模式
- 具有多个继承共享一个资源的对象 - 寻找良好的设计模式
- 在C++中创建观察器设计模式的好方法
- 现代C++在多大程度上消除了对设计模式的需求?
- 对于存储另一个类所需信息的类,例如其构造,是否有设计模式?
- 下面抽象工厂设计模式的实现是正确的吗
- sql记录集函数的状态设计模式
- 克隆设计模式适配器 - 避免切片子项(类似于原型模式)
- 原型设计模式在新的时候使用是昂贵的,但我们在克隆中做新的