C++ 如何向对象添加属性而不破坏其父接口?
我和我的团队正在研究的代码库用于引导物理设备(分光光度计)。它们都非常相似,但有些可以做其他人不能做的事情,它们都有自己的SDK和驱动程序 我们经常需要支持新的设备,每个设备都有自己的特定属性 主设备接口,比如IDevice,有很多纯虚拟接口,用于确定设备(比如Device1、Device2等)是否可以执行给定的操作,或者它支持什么类型的操作 IDevice.hC++ 如何向对象添加属性而不破坏其父接口?,c++,qt,C++,Qt,我和我的团队正在研究的代码库用于引导物理设备(分光光度计)。它们都非常相似,但有些可以做其他人不能做的事情,它们都有自己的SDK和驱动程序 我们经常需要支持新的设备,每个设备都有自己的特定属性 主设备接口,比如IDevice,有很多纯虚拟接口,用于确定设备(比如Device1、Device2等)是否可以执行给定的操作,或者它支持什么类型的操作 IDevice.h class IDevice : public QObject { Q_OBJECT public: virtual ~
class IDevice : public QObject {
Q_OBJECT
public:
virtual ~IDevice() {}
virtual bool canDoOperationA() = 0;
virtual bool canDoOperationB() = 0;
virtual QVariant supportedMode() = 0;
// etc. There are a lot of these ‘canDo’ and ‘supported’ interfaces.
// dozens of other things, slots, signals, etc.
};
class IDevice : public QObject {
Q_OBJECT
public:
virtual ~IDevice() {}
virtual bool canDoOperationA() = 0;
virtual bool canDoOperationB() = 0;
virtual QVariant supportedMode() = 0;
virtual bool canDoOperationC() = 0;
virtual QVariant supportedSpecialMode() = 0;
};
设备1.h
class Device1 : public IDevice {
public:
bool canDoOperationA() { return true; }
bool canDoOperationB() { return false; }
QVariant supportedMode() { return QStringList{{ “m1”, “m2” }}; }
};
设备2.h
class Device2 : public IDevice {
public:
bool canDoOperationA() { return false; }
bool canDoOperationB() { return true; }
QVariant supportedMode() {
return getModesAtRuntime();
}
private:
QVariant getModesAtRuntime() {
/* determine at runtime what modes are supported,
depending on the device current configuration */
return QVariant();
}
} ;
这些属性中的大多数在编译时已知,但其中一些属性(取决于设备)必须在运行时确定(通常通过设备SDK,该SDK允许询问设备本身的状态)
通常,我们需要支持新的设备和/或属性,从而在IDevice中添加其他canDoOperationXXX方法(随着时间的推移变得异常)。例如,如果操作C和特殊模式需要特定设备支持,IDevice将类似于:
IDevice.h
class IDevice : public QObject {
Q_OBJECT
public:
virtual ~IDevice() {}
virtual bool canDoOperationA() = 0;
virtual bool canDoOperationB() = 0;
virtual QVariant supportedMode() = 0;
// etc. There are a lot of these ‘canDo’ and ‘supported’ interfaces.
// dozens of other things, slots, signals, etc.
};
class IDevice : public QObject {
Q_OBJECT
public:
virtual ~IDevice() {}
virtual bool canDoOperationA() = 0;
virtual bool canDoOperationB() = 0;
virtual QVariant supportedMode() = 0;
virtual bool canDoOperationC() = 0;
virtual QVariant supportedSpecialMode() = 0;
};
然后,所有设备都需要更新和重新编译(它们甚至不知道OperationC和SpecialMode)。我认为这是一个设计缺陷
我想知道是否有一种在不破坏API的情况下在设备中添加新属性的最佳方法
我正在考虑从IDevice中删除所有canDoOperation和supportedModes方法,并用单个接口替换它们
QVariant getProperty(const QString& propertyName) = 0;
这样,设备返回自己的属性,无论是运行时还是编译时。如果不支持属性,则返回无效的QVariant。向特定设备添加特定属性不会破坏API,只会重新编译设备
这种方法有什么警告吗?您认为有更好的方法解决此问题吗?QObject已经具有运行时可编辑属性。请参阅和@Caleth。问题是某些属性无法存储,但必须在运行时计算。据我所知,我不能使用QObject::property来实现这一点。你理解错了<代码>QObject::setProperty使用以前未看到的名称添加该属性
QObject::property
与以前未看到的名称一起返回空的QVariant
在某些情况下,我每次都需要从设备本身(通过其SDK)读取属性,因为它们的值会随时间而变化。我可以使用QObject::setProperty设置这些属性,但是每次更改时都应该更新它们。每个设备都会维护自己的属性列表。这可能是一个解决方案。这是一个广泛的主题。解决这个问题的方法有上千种。除了个人意见之外,你不会得到令人满意的答案。作为介绍,您可能希望检查并进一步了解如何实现该目标。QObject已经具有运行时可编辑属性。请参阅和@Caleth。问题是某些属性无法存储,但必须在运行时计算。据我所知,我不能使用QObject::property来实现这一点。你理解错了<代码>QObject::setProperty使用以前未看到的名称添加该属性QObject::property
与以前未看到的名称一起返回空的QVariant
在某些情况下,我每次都需要从设备本身(通过其SDK)读取属性,因为它们的值会随时间而变化。我可以使用QObject::setProperty设置这些属性,但是每次更改时都应该更新它们。每个设备都会维护自己的属性列表。这可能是一个解决方案。这是一个广泛的主题。解决这个问题的方法有上千种。除了个人意见之外,你不会得到令人满意的答案。作为一个介绍,你可能想检查一下,并进一步教育自己如何做到这一点。