gpt4 book ai didi

c++ - 在没有额外代码的情况下链接两个独立类的最通用方法是什么?

转载 作者:搜寻专家 更新时间:2023-10-30 23:51:11 24 4
gpt4 key购买 nike

类的层次结构描述了某个对象的不同属性。抽象类 Property 是一个基类,它有子类:IntegerPropertyBooleanProperty 等。所有数据都在 QString 中编码,派生类以自己的方式对其进行解码。

class Property : public QObject
{
Q_OBJECT

public:
// ...
virtual QString value() const = 0;
virtual bool setValue(const QString &value) = 0;
virtual bool validateValue(const QString& value) = 0;
// ...
};

class IntegerProperty : public Property
{
// ...
virtual QString value() const override;
virtual bool setValue(const QString &value) override;
virtual bool validateValue(const QString& value) override;
// ...
};

// ...

每个属性类都必须有一个独立的编辑器(GUI 小部件)- PropertyEditor(又是抽象类)、IntegerPropertyEditorBooleanPropertyEditor 等等在。

class PropertyEditor : public QWidget
{
Q_OBJECT

public:
inline Facer::PropertyPointer attachedProperty() { return m_property; }

protected:
PropertyEditor(Facer::PropertyPointer attachedProperty, QWidget* parent = nullptr);

virtual void mousePressEvent(QMouseEvent* event) override;
virtual bool eventFilter(QObject *watched, QEvent *event) override;

// ...
};

class IntegerPropertyEditor : public PropertyEditor
{
// ...
};

// ...

例如,我有一组不同的属性。我不知道我到底有哪些属性,因为它们都是指向 Property 类的指针。我的任务是为这些属性创建指定的编辑器,因此如果属性对象是 IntegerProperty,我需要获取 IntegerPropertyEditor

for (Property* property : propertySet())
PropertyEditor* editor = createEditor(property);

我用宏做了一个临时的解决方法:

#define IF_TYPE_GET_EDITOR(propertyType, editorType) \
if (std::dynamic_pointer_cast<propertyType>(property)) \
return new editorType(property, this);

// ...

PropertyEditor *PropertySetWidget::create(PropertyPointer property)
{
IF_TYPE_GET_EDITOR(BooleanProperty, BooleanPropertyEditor)
else IF_TYPE_GET_EDITOR(ColorProperty, ColorPropertyEditor)
else IF_TYPE_GET_EDITOR(FloatingPointProperty, FloatingPointPropertyEditor)
else IF_TYPE_GET_EDITOR(FontProperty, FontPropertyEditor)
else IF_TYPE_GET_EDITOR(IntegerProperty, IntegerPropertyEditor)
else IF_TYPE_GET_EDITOR(TextProperty, TextPropertyEditor)
else throw std::runtime_error("This PropertyType is not implemented yet");
}

这看起来不是一个好的解决方案 - 如果我添加一种新类型的属性及其编辑器,我也必须更新此代码。链接编辑器类和属性类的最方便和通用的方法是什么?

最佳答案

这可能会提供一些额外的代码,特别是取决于您的项目是如何设置的,但一种解决方案是在 Property 中创建一个返回指向编辑器指针的虚函数:

class Property : public QObject
{
public:
virtual PropertyEditor* CreateEditor(PropertySetWidget* widget) {
// let's put our default behavior here
throw std::runtime_error("This PropertyType is not implemented yet");
}
//...
};

现在,您让每个类负责提供自己的编辑器:

class IntegerProperty : public Property
{
public:
// doesn't have to be virtual, I don't think Just a regular version should be fine too.
virtual PropertyEditor* CreateEditor(PropertySetWidget* widget) {
return new IntegerPropertyEditor(this, widget);
}
//...
};

根据您拥有的类(class)数量,可能需要进行大量复制和粘贴操作。

然而,有趣的部分是 PropertySetWidget::create():

PropertyEditor *PropertySetWidget::create(PropertyPointer property)
{
return property->CreateEditor(this);
}

因为 property 的每个 child 都负责提供自己的编辑器,所以我们不必在这个级别上担心它。如果不存在/未实现,property::CreateEditor() 将为您抛出错误。如果确实存在/已实现,它将自动向编辑器返回一个指向新实例的指针。

最大的好处是,如果你添加一个新的属性和它的编辑器,你根本不必去触及它这个功能。虚函数负责为您正确实现它。如果新属性有一个编辑器,它只需要重载那个函数,这个 create() 仍然可以正常工作。

当然,您将不得不以这种方式修改Property 的接口(interface),这在您的情况下可能不可行。这是这种方法的主要缺点。

关于c++ - 在没有额外代码的情况下链接两个独立类的最通用方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57386576/

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