如何在静态方法中实例化当前类的实例

How to instantiate an instance of the current class in a static method?

本文关键字:实例 实例化 静态方法      更新时间:2023-10-16

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

class MyClass : public QObject
{
    Q_OBJECT
    public:
        virtual void doSomething();
        static void createInstance();
};

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

起初我认为模板可能是一个解决方案,但下面的代码:

template <typename T>
static void createInstance();
// ...in myclass.cpp...
template <typename T>
void MyClass::createInstance()
{
    T().doSomething();
}

…产生以下链接器错误:

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

这个答案可能是有效的,除了moc不能与模板类一起工作。我有什么选择?

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将能够处理它。模板类的存在仅仅是为了创建具有编译时调度的静态方法,而不必一遍又一遍地编写它,也不必每次调用它时都重复自己。如果不是,你总是可以回到第一个版本。