gpt4 book ai didi

c++ - 为什么以及如何使用原型(prototype)设计模式

转载 作者:行者123 更新时间:2023-12-01 14:05:59 25 4
gpt4 key购买 nike

我正在学习设计模式并尝试自己实现它们。对于大多数设计模式,我可以理解其中的使用和实现,但我对原型(prototype)模式感到困惑。这是我实现它的方法。

船舶.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 Info\t\n" <<
"Name:\t\t" << shipName << "\n" <<
"Width:\t\t" << width << "\n" <<
"Height:\t\t" << height << "\n" <<
"Speed:\t\t" << 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;
}

让我困惑的部分是克隆函数返回接口(interface)的指针,这意味着我不能将克隆存储在不同的船舶对象中,例如。 Ship* ship = factory->CreateCloneShip(0); .

我认为这种设计模式背后的想法是创建一个已经存在的对象的克隆,然后更改它的一些细节。
是我的实现不正确还是我遗漏了什么?

最佳答案

原型(prototype)模式允许我们通过调用虚成员函数来多态地创建对象的拷贝,通常称为 clone(),就像你的代码一样。

Part which confuses me is that clone function returns the pointer for Interface, which means I can't store the clone in a different ship object



通常,覆盖函数的类型必须与其覆盖的虚函数的类型完全相同。但是,如果要覆盖的虚函数返回一个(原始)指针或引用,则对于允许覆盖函数返回的类型有一些约束放松。

如果是这种情况,则覆盖函数的返回类型可能是指针或对被覆盖函数返回指针的类类型的派生类的引用。这被称为 covariant return type的一种方法。

现在,考虑到这一点并专注于 IShipPrototype::clone()虚成员函数。它返回一个 IShipPrototype* :
class IShipPrototype {
public:
virtual IShipPrototype* clone() = 0; // returns IShipPrototype*
// ...
};

由于 IShipPrototypeShip 的公共(public)基础, 一个最重要的 Ship::clone()可以返回 Ship*而不是 IShipPrototype* :
class Ship: public IShipPrototype {
public:
Ship* clone() override; // returns Ship*
// ...
};

这样,如果您有 Ship对象,您调用 clone()直接在上面,你会得到一个 Ship* ,而不是 IShipPrototype* ——尽管 Ship*隐式转换为 IShipPrototype*因为 IShipPrototypeShip 的公共(public)基类. IShipPrototypeShip这里被称为协变类型。

请注意,如果您调用 clone()通过 IShipPrototype接口(interface),返回指针指向的类型的静态类型为 IShipPrototype* .然而,动态类型将是 Ship如果在 Ship 上调用它实例。

关于c++ - 为什么以及如何使用原型(prototype)设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61923289/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com