由于我在面向对象代码的设计方面不是很有经验,所以我有以下问题:
我有一个组合框 cb_GRAN ,有21个条目代表21种几何形状。根据 cb_GRAN 中的选择,我想开始对几何体表面进行不同的计算(实际上还有更多:更复杂的计算,LineEdits的切换等等,但要保持简单让它我只是谈谈表面的计算。)
为了解决这个问题,我创建了一个Geometry类和21个类( Geo_1,Geo_2,... Geo_21 ),这些类继承自Geometry。我也有一个虚方法
virtual void calculateSurface();
要定义 Geo_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();
答案 0 :(得分:1)
问题1: 您的解决方案可能会运行良好(仅基于您提供的信息)。
问题2: 你是完全正确的,如果你打算只使用其中的一个或两个,那么创建你所有21个类的实例可能是一个过度杀伤。
您必须找到一个解决方案来仅实例化所需的类。 Qt提供了一个可用于此的元对象系统。基本上,您必须使用QMetaType class。
首先,您必须注册&#34; Geo_N&#34;元对象系统中的类。你有很多解决方案可以做到这一点,但在你的情况下最好的方法是在你的类定义之后使用声明性宏:
class Geo_1 {
Q_OBJECT
void Geo_1();
};
Q_DECLARE_METATYPE(Geo_1);
请注意,如果要在元对象注册表中注册类,则必须使用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);
答案 1 :(得分:0)
我的方法是为几何定义工厂类
class GeoFactory{
enum GeometryType { GEO_1, GEO_2, ... );
std::uique_ptr<Geometry> create( GeometryType type );
}
然后将GeometryType添加到数据角色中的组合框项目中。在当前更改的事件上,您只需从当前索引中检索GeometryType,并从工厂请求相应的对象。
就我个人而言,我总是尝试将Qt与实际业务逻辑保持一致,我只是用于UI。