工厂设计 C++/QtCreator
Factory Design C++/QtCreator
我正在尝试实施工厂设计模式。我使用 class 'Factory' 的静态成员函数创建 returns 'Candy' 的实例,但对用户隐藏 class 模块的详细信息。
我的头文件贴在下面:
#ifndef CANDY_H
#define CANDY_H
#include <QColor>
#include <QGraphicsItem>
#include <QGraphicsSceneMouseEvent>
#include <QDebug>
#include <QLayoutItem>
#include <QIcon>
#include <QFont>
enum class CandyType {Normal, Powerup};
enum class PowerUpType {None, Wrapped, Striped, Sour};
class Candy : public QObject, public QGraphicsItem
{
// this makes it so that we can emit signals
Q_OBJECT
public:
//static std::vector<CandyType> enum_vec;
//Candy(QColor color, const int i, const int j);
Candy();
int get_i() const { return j_; } // inline member function
int get_j() const { return i_; } // inline member function
QColor get_color() const { return color_; }
//CandyType get_candy_type() const { return candy_type_; }
std::vector<Candy*> get_neighbors() { return neighbors_; }
QRectF boundingRect() const override;
QPainterPath shape() const override;
void SwapCandy(Candy *c);
void StoreNeighbors(std::vector<Candy*> neighbors_vec);
void Poof();
void setIJ(int i, int j);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) override;
signals:
void StoreSwapCandySelected(Candy *c);
void SwapCandySelected(Candy *c);
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
private:
int i_;
int j_;
QColor color_;
QFont myFont;
bool next_state;
static const int width_ = 35;
std::vector<Candy*> neighbors_;
}; // class RegCandy
// CANDY_H
/*INHERITED CLASS -- the functions that shoudl be different from parent
* are the constructor and the mousepressevent. In addition some feilds
* and getters are unnecessary and some added functions are used*/
class PowerUp : public Candy
{
Q_OBJECT
public:
static std::vector<PowerUpType> enum_vec;
PowerUp() : Candy() {}
std::string CandyTypeToString() {
if (powerup_type_ == PowerUpType::Wrapped) {
return "Wrapped";
} else if (powerup_type_ == PowerUpType::Striped) {
return "Striped";
} else {
return "Sour";
}
}
PowerUpType get_candy_type() const { return powerup_type_; }
void setPUType(PowerUpType p_type) {
this->powerup_type_ = p_type;
}
void setColor(QColor color) {
this->color_ = color;
}
void setEmpty() {
empty_ = true;
}
void setFull() {
empty_ = false;
}
bool isEmpty() { return empty_; }
signals:
void StorePowerUpSelected(PowerUp *p);
protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override {
if (event->button() == Qt::LeftButton) {
//qDebug() << QString::fromStdString(this->CandyTypeToString()) << ": " << this->get_i() << "," << this->get_j();
emit StorePowerUpSelected(this);
}
update();
}
private:
int i_;
int j_;
PowerUpType powerup_type_;
QColor color_;
bool empty_ = true;;
//bool next_state;
static const int width_ = 35;
}; //class PowerUp
class Factory {
public:
/*~Factory() {
if (c_type) {
delete[] c_type;
c_type = NULL;
}
}*/
static Candy* getCandy(CandyType type) {
if (type == CandyType::Normal)
return new Candy();
else if (type == CandyType::Powerup)
return new PowerUp();
else return NULL;
}
};
#endif
目前我的 PowerUp class 继承自我的 Candy class,我想使用 Factory::getCandy() 创建每个对象的实例,但是当我尝试调用静态像这样的 getCandy() 方法:
PowerUp *p = Factory::getCandy(CandyType::Powerup);
我收到以下错误,'error: cannot initialize a variable of type PowerUp * with an rvalue of type Candy *'
我认为通过使 'PowerUp' class 继承自 'Candy' class 我可以将 return 值 Candy* 存储在 PowerUp* 中,但在对继承进行更多思考之后,似乎逻辑遵循类似 'Every PowerUp is a Candy, but not every Candy is a PowerUp' 的内容,因此也许应该写下该行:
Candy *c = Factory::getCandy(CandyType::Powerup);
但是我需要'PowerUp'糖果有一些不同于超级class的方法,所以我不知道为什么我会存储[=42=的return值]() 在 Candy* 中,如果我特别想要一个 PowerUp* 的实例。
注意:使用以下行创建 'Candy' 的实例时效果很好:
Candy *c = Factory::getCandy(CandyType::Normal)
我知道我的实现可能并不完美,这是我第一次尝试将工厂设计添加到我的代码中,但它似乎对我的程序非常有用。非常感谢任何指针。提前致谢!
你说:
However I need the PowerUp
candies to have some different methods
than the superclass, so I do not know why I would store the return
value of Factory::getCandy()
in Candy*
if I specifically want an
instance of PowerUp*
.
如果这是真的,工厂就没有意义了,使用一个简单的构造函数。工厂的全部意义在于通过共享 公共接口 来抽象细节(比如你的 Candy
实际上是 PowerUp
的事实) .在您的情况下,如果应用程序知道它使用的特定类型并调用只有该类型具有的方法,则意味着没有抽象。
你可以:
- 删除工厂并使用经典构造函数。
- 检查您的
Candy
抽象以使 PowerUp
成为真正的实现细节。最后,在调用代码的眼中,使用PowerUp
和任何其他类似Candy
的类型应该没有区别。
我正在尝试实施工厂设计模式。我使用 class 'Factory' 的静态成员函数创建 returns 'Candy' 的实例,但对用户隐藏 class 模块的详细信息。
我的头文件贴在下面:
#ifndef CANDY_H
#define CANDY_H
#include <QColor>
#include <QGraphicsItem>
#include <QGraphicsSceneMouseEvent>
#include <QDebug>
#include <QLayoutItem>
#include <QIcon>
#include <QFont>
enum class CandyType {Normal, Powerup};
enum class PowerUpType {None, Wrapped, Striped, Sour};
class Candy : public QObject, public QGraphicsItem
{
// this makes it so that we can emit signals
Q_OBJECT
public:
//static std::vector<CandyType> enum_vec;
//Candy(QColor color, const int i, const int j);
Candy();
int get_i() const { return j_; } // inline member function
int get_j() const { return i_; } // inline member function
QColor get_color() const { return color_; }
//CandyType get_candy_type() const { return candy_type_; }
std::vector<Candy*> get_neighbors() { return neighbors_; }
QRectF boundingRect() const override;
QPainterPath shape() const override;
void SwapCandy(Candy *c);
void StoreNeighbors(std::vector<Candy*> neighbors_vec);
void Poof();
void setIJ(int i, int j);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) override;
signals:
void StoreSwapCandySelected(Candy *c);
void SwapCandySelected(Candy *c);
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
private:
int i_;
int j_;
QColor color_;
QFont myFont;
bool next_state;
static const int width_ = 35;
std::vector<Candy*> neighbors_;
}; // class RegCandy
// CANDY_H
/*INHERITED CLASS -- the functions that shoudl be different from parent
* are the constructor and the mousepressevent. In addition some feilds
* and getters are unnecessary and some added functions are used*/
class PowerUp : public Candy
{
Q_OBJECT
public:
static std::vector<PowerUpType> enum_vec;
PowerUp() : Candy() {}
std::string CandyTypeToString() {
if (powerup_type_ == PowerUpType::Wrapped) {
return "Wrapped";
} else if (powerup_type_ == PowerUpType::Striped) {
return "Striped";
} else {
return "Sour";
}
}
PowerUpType get_candy_type() const { return powerup_type_; }
void setPUType(PowerUpType p_type) {
this->powerup_type_ = p_type;
}
void setColor(QColor color) {
this->color_ = color;
}
void setEmpty() {
empty_ = true;
}
void setFull() {
empty_ = false;
}
bool isEmpty() { return empty_; }
signals:
void StorePowerUpSelected(PowerUp *p);
protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override {
if (event->button() == Qt::LeftButton) {
//qDebug() << QString::fromStdString(this->CandyTypeToString()) << ": " << this->get_i() << "," << this->get_j();
emit StorePowerUpSelected(this);
}
update();
}
private:
int i_;
int j_;
PowerUpType powerup_type_;
QColor color_;
bool empty_ = true;;
//bool next_state;
static const int width_ = 35;
}; //class PowerUp
class Factory {
public:
/*~Factory() {
if (c_type) {
delete[] c_type;
c_type = NULL;
}
}*/
static Candy* getCandy(CandyType type) {
if (type == CandyType::Normal)
return new Candy();
else if (type == CandyType::Powerup)
return new PowerUp();
else return NULL;
}
};
#endif
目前我的 PowerUp class 继承自我的 Candy class,我想使用 Factory::getCandy() 创建每个对象的实例,但是当我尝试调用静态像这样的 getCandy() 方法:
PowerUp *p = Factory::getCandy(CandyType::Powerup);
我收到以下错误,'error: cannot initialize a variable of type PowerUp * with an rvalue of type Candy *'
我认为通过使 'PowerUp' class 继承自 'Candy' class 我可以将 return 值 Candy* 存储在 PowerUp* 中,但在对继承进行更多思考之后,似乎逻辑遵循类似 'Every PowerUp is a Candy, but not every Candy is a PowerUp' 的内容,因此也许应该写下该行:
Candy *c = Factory::getCandy(CandyType::Powerup);
但是我需要'PowerUp'糖果有一些不同于超级class的方法,所以我不知道为什么我会存储[=42=的return值]() 在 Candy* 中,如果我特别想要一个 PowerUp* 的实例。
注意:使用以下行创建 'Candy' 的实例时效果很好:
Candy *c = Factory::getCandy(CandyType::Normal)
我知道我的实现可能并不完美,这是我第一次尝试将工厂设计添加到我的代码中,但它似乎对我的程序非常有用。非常感谢任何指针。提前致谢!
你说:
However I need the
PowerUp
candies to have some different methods than the superclass, so I do not know why I would store the return value ofFactory::getCandy()
inCandy*
if I specifically want an instance ofPowerUp*
.
如果这是真的,工厂就没有意义了,使用一个简单的构造函数。工厂的全部意义在于通过共享 公共接口 来抽象细节(比如你的 Candy
实际上是 PowerUp
的事实) .在您的情况下,如果应用程序知道它使用的特定类型并调用只有该类型具有的方法,则意味着没有抽象。
你可以:
- 删除工厂并使用经典构造函数。
- 检查您的
Candy
抽象以使PowerUp
成为真正的实现细节。最后,在调用代码的眼中,使用PowerUp
和任何其他类似Candy
的类型应该没有区别。