1

我有一个看起来像这样的 Qt 类:

class MyClass : public QObject
{
    Q_OBJECT

    public:

        virtual void doSomething();
        static void createInstance();
};

createInstance方法应该创建当前类的实例并doSomething在其上调用该方法。例如,如果我创建一个名为 的派生类MyOtherClasscreateInstance应该创建一个实例MyOtherClass并在该实例上调用doSomething

起初我认为模板可能是这里的解决方案,但以下代码:

template <typename T>
static void createInstance();

// ...in myclass.cpp...

template <typename T>
void MyClass::createInstance()
{
    T().doSomething();
}

...产生以下链接器错误:

错误:未定义对 `void MyClass::createInstance<MyOtherClass>()' 的引用

这个答案可能有效,但moc不适用于模板类。我有什么选择?

4

1 回答 1

2

把实现createInstance放在你的头文件中。使用的每个编译单元都createInstance<Foo>需要能够创建实现。

作为改进,创建一个两层系统:

class MyClassBase: public QObject {
  Q_OBJECT
public:
  virtual void doSomething() = 0;
};

template<typename Derived>
class MyClass: public MyClassBase {
public:
  static void createInstanceAndDoSomething() {
    Derived d;
    d.doSomething();
  }
};

然后,从 MyClass 继承时,传入派生类:

class DerivedClass: MyClass<DerivedClass> {
  // ...
};

你也可以抛出一些静态(或者,如果你的编译器没有)运行时断言,它DerivedMyClass<Derived>. MyClass<Derived>只是为了保持理智。

通过仅Q_OBJECT在具体类中使用(而不是在模板类中),我希望您moc能够处理它。模板类的存在只是为了创建具有编译时调度的静态方法,而不必一次又一次地编写它,也不必每次调用它时都重复自己。如果没有,您可以随时退回到第一个版本。

于 2013-04-03T01:12:35.487 回答