在定义自定义接口时继承库类

Inheriting library class while defining custom interface

本文关键字:继承 接口 定义 自定义      更新时间:2023-10-16

我遇到了以下设计问题:

我正在使用Qt c++库的应用程序。在这个库中有"模型"类,它们都继承自QAbstractItemModel(如QAbstractTableModel, QStandardItemModel等)。我想继承这些类中的几个,但是定义我自己的接口,它们必须每个共享。

我目前这样做的方式是通过定义一个接口(纯虚拟类),并有继承类从这个继承。作为一个例子,假设我想要一个从QAbstractTableModel继承的类具有doSomething函数:

class MyInterface {
public:
    virtual void doSomething() = 0;
}
class MyModel : public QAbstractTableModel, public MyInterface {
    ...
}

然而,我只是想传递对象作为QAbstractItemModel。为了使用接口类,我必须将它们强制转换为MyInterface对象,然后调用函数,这会导致到处都是强制转换。此外,如果其他人从QAbstractItemModel继承自己的类,如果他们不继承接口,似乎有错误的空间。

有没有更好的设计可以让我完成这一切?

您使用的是哪种类型的cast ?如果你使用dynamic_cast,你的代码不会看起来更好,但是如果你总是检查转换的null-result,你至少应该对非接口类可能出现的错误没有问题。

当有大量可能的类(如MyModel)时,这会变得更加复杂,因为您不能直接从QAbstractTableModel强制转换(动态或静态)到MyInterface -您需要尝试将它们全部强制转换,以便稍后向下强制转换为接口类。一种解决方案可能是使用一些模板技巧-

class MyInterface {
public:
    virtual void doSomething() = 0;
}
template <typename T>
class MyTemplatedInterface: public T, public MyInterface {
private:
    virtual void foo(){}; // might be neceseary to be able to dynamic_cast to this type
}
class MyModel: public MyTemplatedInterface<QAbstractTableModel>{
public:
virtual void doSomething(){};
}

这样,如果你得到QAbstractTableModel指针并想知道它是否实现了MyInterface,你只需将其转换为MyTemplatedInterface,而不管实际的基本实现类型是什么。这种设计有几个缺陷,比如不能处理多个接口,或者不能声明模板化类的构造函数——其中大多数缺陷将在c++0x中被删除,但目前还没有编译器实现足够的功能来编写依赖于它的代码。

是。首先,根本不要使用MyInterface类。当你想接受任何具有doSomething()方法的对象时,使用模板。如果您"以QAbstractModel的形式传递对象",这意味着您正在编写接受QAbstractModel类型的任何对象的函数,其中一些对象可能不是MyModel的(甚至不是MyInterface的)。如果调用doSomething,那么就违反了函数接受QAbstractModel类型的任何对象的约定。