2013-04-03 54 views
1

我有一個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(); 
} 

...生成以下鏈接錯誤:

error: undefined reference to `void MyClass::createInstance<MyOtherClass>()'

This answer可能除了moc沒有按工作過不適用於模板類。我有什麼選擇?

回答

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> { 
    // ... 
}; 

你也可以扔在一些靜態(或者,如果你的編譯器不具有)運行時斷言Derived是在MyClass<Derived>身體派生類的MyClass<Derived>。只是爲了讓事情保持健全。

只在具體類(而不是模板類)中使用Q_OBJECT,我希望你的moc能夠處理它。模板類僅僅是爲了創建具有編譯時間調度的靜態方法而不必一次又一次地編寫它,並且每次調用它時不必重複自己。如果沒有,你可以回到第一個版本。

+0

非常有趣的想法。謝謝! –