我有两个接口,如下所示:
class IThing {
...
virtual IHandle* getHandle(void) = 0;
virtual void useHandle(IHandle *handle) = 0;
};
class IHandle { ... }
我希望用户能够实现IThing和IHandle。例如,如果用户创建MyThing
和MyHandle
,则getHandle
应返回指向MyHandle
的指针,用户稍后可在useHandle
中使用该指针。 / p>
这样可行,但我不喜欢这种设计,因为IHandle
的多个实现可能会在IThing
的实现之间混淆。同样在useHandle
中,用户需要明确地向下转换为IHandle
的实现。是否有更安全的方式来做到这一点?
答案 0 :(得分:0)
我不太确定你想要设计什么。但在这里,我希望有些想法可能会有所帮助。
基本原则是公开派生自IThing
的类确实是IThing
。您可以使用IThing
执行此操作,您可以使用MyThing
,包括获取IHandle
。
只要您的IHandle
衍生品都遵循相同的原则,就没有设计问题。这意味着您的东西不应该对特定句柄做出任何假设,反之亦然。
如果您使用MyHandle
假设与MyThing
相关联(或反之亦然),那么您将会遇到您描述的问题。实际上,您使用的是在类定义中未表达的依赖项。所以,是的,你将不得不使用垂头丧气。这是不可能的,因为它揭示了一个设计问题。
由于您的类是多态的,您可以通过使用dynamic_cast
检查nullptr来限制向下转换风险。但这是一种解决方法,而不是设计改进。
或者你可以考虑模板。它们可以帮助您在编译时链接相关类型。您将获得类型安全性,但是您将失去运行时多态性的一些灵活性。一个示例方法:
template <class IH>
class IThing {
public:
virtual IH* getHandle(void) =0;
virtual void useHandle(IH *handle) =0;
};
class MyHandle { }; // to keep it simple,
class MyThing: public IThing<MyHandle> {}; // instantiation with specific handle
int main() {
MyThing i;
MyHandle *h;
h = i.getHandle();
...
}
此示例中的约束是,您不要使用不同的句柄混合不同的IThings
。