C++ 定义自定义接口时继承库类

C++ 定义自定义接口时继承库类,c++,oop,qt,C++,Oop,Qt,我遇到了以下设计问题: 我正在使用Qt C++库来进行应用程序。在这个库中,有一些模型类,它们都继承自QAbstractItemModel,如QAbstractTableModel、QStandarditItemModel等。。我想继承其中几个类,但定义自己的接口,它们必须共享 我目前的做法是定义一个接口纯虚拟类,并让继承类也从中继承。例如,假设我希望从QabStretctTableModel继承的类具有doSomething函数: class MyInterface { public:

我遇到了以下设计问题:

我正在使用Qt C++库来进行应用程序。在这个库中,有一些模型类,它们都继承自QAbstractItemModel,如QAbstractTableModel、QStandarditItemModel等。。我想继承其中几个类,但定义自己的接口,它们必须共享

我目前的做法是定义一个接口纯虚拟类,并让继承类也从中继承。例如,假设我希望从QabStretctTableModel继承的类具有doSomething函数:

class MyInterface {
public:
    virtual void doSomething() = 0;
}
class MyModel : public QAbstractTableModel, public MyInterface {
    ...
}
但是,我只想将对象作为QabstracteModel传递。要使用接口类,我必须将它们转换为MyInterface对象,然后调用函数,这会导致到处转换。此外,如果其他任何人从QAbstractItemModel继承自己的类,那么如果他们不继承接口,则似乎存在错误的空间


有没有更好的设计可以用来完成这一切?

是的。首先,不要使用MyInterface类。要获取任何具有剂量测量方法的对象时,请使用模板。如果您将对象作为QAbstractModel传递,这意味着您正在编写接受QAbstractModel类型的任何对象的函数,其中一些对象可能不是MyModel的,甚至不是MyInterface的。如果您调用doSomething,那么您违反了函数接受QabStretchModel类型的任何对象的约定。

您使用哪种类型的强制转换?如果您使用dynamic_cast,您的代码看起来不会更好,但是如果您总是检查强制转换的空结果,那么您至少应该对非接口类可能出现的错误感到满意

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

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(){};
}

这样,如果您获得QabStretctTableModel指针,并想知道它是否实现了MyInterface,那么您只需将其强制转换为MyTemplatedInterface,而不管实际的基本实现类型是什么。此设计有几个缺陷,例如无法处理多个接口或声明模板类的构造函数-其中大多数将在c++0x中删除,但是在这一点上,没有编译器实现足够多的类来编写依赖于它的代码。

要让模板系统知道对象有doSomething方法,它需要知道这个类不仅仅是QAbstractTableModel,当只有QAbstractTableModel指针/引用(例如来自Qt函数)可用时,仍然需要强制转换-因此这根本不能解决问题MyInterface类根本不能解决任何问题。这可能是在有问题需要解决之前尝试使用C++的所有特性。这是我正在打破的合同的一个好想法。这让我觉得我应该重新思考我在整个问题上的立场。Qt有解决直接铸造问题的方法。它仍然很难看。如果MyInterface没有继承QObject,并且它不能继承,如果它与另一个QObject Decentant相乘继承,那么QObject_cast将无法使用它。