Qt C++ 根据组合框中的选择创建对象
Qt C++ creating an Object according to choice in combobox
由于本人对面向对象代码的设计经验不是很丰富,所以有以下问题:
我有一个组合框 cb_GRAN,其中包含 21 个条目,代表 21 个几何图形。根据 cb_GRAN 中的选择,我想开始对我的几何体表面进行不同的计算(实际上还有更多:更复杂的计算,on/of-switching LineEdits 等.但为了简单起见,我们只讨论曲面的计算。)
为了解决这个问题,我创建了一个 class Geometry 和 21 类 (Geo_1, Geo_2,...Geo_21) 继承自 Geometry。我还有一个虚方法
virtual void calculateSurface();
为了定义classGeo_x是创建和计算表面,我想到了以下想法:
Geometry *GEO;
QVector < Geometry*> qvec_GEO
qvec_GEO << new Geo_1()<< new Geo_2()<< new Geo_3()<<...... << new Geo_21() ;
GEO = qvec_GEO[ui->cb_GRAN->currentIndex()];
GEO->calculateSurface();
- 这是否是解决我的问题的可行方法,或者这样做时我 运行 会遇到问题吗?
- 创建尽可能多的是个好主意吗
21 个对象,而我只需要一个?
问题一:
您的解决方案可能会运行良好(仅基于您提供的信息)。
问题二:
你完全正确,如果你打算只使用其中的 1 个或 2 个,则创建所有 21 个 class 的实例可能是一种矫枉过正。
您必须找到一种解决方案来仅实例化所需的 class。 Qt 提供了一个元对象系统,您可以为此使用。基本上,您将不得不使用 QMetaType class.
首先,您必须在元对象系统中注册 "Geo_N" classes。您有很多解决方案可以做到这一点,但在您的情况下最好的方法可能是在 class 定义之后使用声明性宏:
class Geo_1 {
Q_OBJECT
void Geo_1();
};
Q_DECLARE_METATYPE(Geo_1);
请注意,如果您想在元对象注册表中注册 class,则必须使用 Q_OBJECT 宏。
然后,您将能够动态实例化任何已注册的类型:
// The index of selected class (between 1 and 21)
int geoIndex = ui->cb_GRAN->currentIndex();
// Re-build the corresponding class name
QString typeName = "Geo_" + QString::number(geoIndex);
// Retrieve the type ID corresponding to the type name
int typeId = QMetaType::type(typeName.toStdString().c_str());
// Instantiate the corresponding class
Geometry* geo = (Geometry*) QMetaType::construct(typeId);
我的方法是为您的几何图形定义一个工厂class
class GeoFactory{
enum GeometryType { GEO_1, GEO_2, ... );
std::uique_ptr<Geometry> create( GeometryType type );
}
然后将 GeometryType 添加到数据角色中的组合框项目。在当前更改的事件中,您只需从当前索引中检索 GeometryType 并从工厂请求相应的对象。
就我个人而言,我总是尽量让 Qt 远离实际的业务逻辑,我只使用 for UI。
由于本人对面向对象代码的设计经验不是很丰富,所以有以下问题:
我有一个组合框 cb_GRAN,其中包含 21 个条目,代表 21 个几何图形。根据 cb_GRAN 中的选择,我想开始对我的几何体表面进行不同的计算(实际上还有更多:更复杂的计算,on/of-switching LineEdits 等.但为了简单起见,我们只讨论曲面的计算。)
为了解决这个问题,我创建了一个 class Geometry 和 21 类 (Geo_1, Geo_2,...Geo_21) 继承自 Geometry。我还有一个虚方法
virtual void calculateSurface();
为了定义classGeo_x是创建和计算表面,我想到了以下想法:
Geometry *GEO;
QVector < Geometry*> qvec_GEO
qvec_GEO << new Geo_1()<< new Geo_2()<< new Geo_3()<<...... << new Geo_21() ;
GEO = qvec_GEO[ui->cb_GRAN->currentIndex()];
GEO->calculateSurface();
- 这是否是解决我的问题的可行方法,或者这样做时我 运行 会遇到问题吗?
- 创建尽可能多的是个好主意吗 21 个对象,而我只需要一个?
问题一: 您的解决方案可能会运行良好(仅基于您提供的信息)。
问题二: 你完全正确,如果你打算只使用其中的 1 个或 2 个,则创建所有 21 个 class 的实例可能是一种矫枉过正。
您必须找到一种解决方案来仅实例化所需的 class。 Qt 提供了一个元对象系统,您可以为此使用。基本上,您将不得不使用 QMetaType class.
首先,您必须在元对象系统中注册 "Geo_N" classes。您有很多解决方案可以做到这一点,但在您的情况下最好的方法可能是在 class 定义之后使用声明性宏:
class Geo_1 {
Q_OBJECT
void Geo_1();
};
Q_DECLARE_METATYPE(Geo_1);
请注意,如果您想在元对象注册表中注册 class,则必须使用 Q_OBJECT 宏。
然后,您将能够动态实例化任何已注册的类型:
// The index of selected class (between 1 and 21)
int geoIndex = ui->cb_GRAN->currentIndex();
// Re-build the corresponding class name
QString typeName = "Geo_" + QString::number(geoIndex);
// Retrieve the type ID corresponding to the type name
int typeId = QMetaType::type(typeName.toStdString().c_str());
// Instantiate the corresponding class
Geometry* geo = (Geometry*) QMetaType::construct(typeId);
我的方法是为您的几何图形定义一个工厂class
class GeoFactory{
enum GeometryType { GEO_1, GEO_2, ... );
std::uique_ptr<Geometry> create( GeometryType type );
}
然后将 GeometryType 添加到数据角色中的组合框项目。在当前更改的事件中,您只需从当前索引中检索 GeometryType 并从工厂请求相应的对象。
就我个人而言,我总是尽量让 Qt 远离实际的业务逻辑,我只使用 for UI。