2011-04-22 88 views
1

我有一個基類自選畫面&我希望始終在其構造函數中調用函數initComponents(),即使對於此類的子類也是如此。但是如果子類已經覆蓋了initComponents()函數,那麼我想讓MyClass調用子類的initComponents()版本,而不是initComponents()的超類(MyScreen)版本。父類可能會調用其子類版本的函數

是否有可能在MyClasses構造函數中做到這一點?

class MyScreen 
{ 
    public: 
    MyScreen() 
    { 
     // a child of this class (& any instance of this class) should always call the initComponents() from this constructor 
     initComponents(); 
    } 

    void initComponents() 
    { 
     // initialise mainLayout, etc, usually this function wont be overridden, sometimes it will be 
    } 

    protected: 
     Layout *mainLayout; 
}; 

class MenuScreen : public MyScreen 
{ 
    public: 
    MenuScreen : public MyScreen() 
    { 
     // I know I could just call initComponents from here, but this is just an example, somethings must be called from the base class 
    } 

    void initComponents() 
    { 
     // create layout, set main layout etc. 
     mainLayout = new MenuLayout(...); 
    } 
}; 
+0

不可以。把你的構建邏輯放在構造函數中。 – 2011-04-22 11:00:12

回答

1

不,你不能這樣做。在MyScreen的構造函數中,該對象的動態類型始終爲MyScreen。你不能從裏面調用MenuScreen函數。

3

你不應該(或者甚至不能)這樣做。問題是,當構造派生類的對象時,基類構造函數總是在派生類之前調用​​。這意味着派生對象還沒有被創建,所以它的成員不會被初始化(這可能對v表也是有效的,所以虛函數調用將不起作用)。檢查this article

相反,你應該用你的類的用戶顯式調用的initComponents並將其標記虛擬

0

填充的資源通過調用虛函數是通過使用內部類可以。下面是一個例子

#ifndef CLAZYSTATICRESOURCINITIALIZATIONASPECT_H 
#define CLAZYSTATICRESOURCINITIALIZATIONASPECT_H 

#include <boost/thread/mutex.hpp> 

template <typename R> 
class CLazyStaticResourceInitialization 
{ 
public: 

    /** 
    * Destructor 
    */ 
    virtual ~CLazyStaticResourceInitialization() 
    { 
    } 

protected: 

    /** 
    * Internal class used for calling virtual function from constructor 
    */ 
    struct parent_virtual 
    { 
     /** 
     * Virtual destructor 
     */ 
     virtual ~parent_virtual() 
     { 
     } 
     /** 
     * Virtual method implemented by parent class is necessary 
     */ 
     virtual void initializeOnce() const 
     { 
     } 
    }; 

    /** 
    * Constructor that can call a virtual function of the parent 
    * @param obj specifies the virtual function 
    */ 
    CLazyStaticResourceInitialization(const parent_virtual& obj) 
    { 
     boost::mutex::scoped_lock scoped_lock(m_Mutex); 

     //Initialize the resource only once 
     if (isInitialized() == false) 
     { 
      obj.initializeOnce(); 

      setInitialized(); 
     } 
    } 

    /** 
    * Returns if any instance of this class has been initialized or not 
    * @return true if initialized, false otherwise 
    */ 
    bool isInitialized() const 
    { 
     return m_bInitialized;; 
    } 

    /** 
    * Returns if any instance of this class has been initialized or not 
    */ 
    void setInitialized() 
    { 
     m_bInitialized = true; 
    } 

protected: 

    /** 
    * The flag that indicates whether this class is initialized or not 
    */ 
    static volatile bool m_bInitialized; 

    /** 
    * The resource instance 
    */ 
    static R  m_Resource; 

    /** 
    * The mutex to protect initialized flag 
    */ 
    static boost::mutex  m_Mutex; 


}; 

//Assume that this class is not initialized in the beginning 
template <typename R> volatile bool CLazyStaticResourceInitialization<R>::m_bInitialized = false; 

//Create a static instance of resource 
template <typename R> R CLazyStaticResourceInitialization<R>::m_Resource; 

//Create a static instance of mutex 
template <typename R> boost::mutex CLazyStaticResourceInitialization<R>::m_Mutex; 


#endif 

這裏是你如何使用它

class CTestLazyInitialized : public CLazyStaticResourceInitialization <std::vector<int> > 
{ 
public: 
    CTestLazyInitialized(): 
    CLazyStaticResourceInitialization<std::vector<int> >(lazyderived_virtual()) 
    { 
    } 

    unsigned int size() 
    { 
     return this->m_Resource.size(); 
    } 
protected: 

    struct lazyderived_virtual : public CLazyStaticResourceInitialization <std::vector<int> >::parent_virtual 
    { 

     lazyderived_virtual() 
     { 
     } 

     void initializeOnce() const 
     { 
      m_Resource.push_back (1); 
     } 

    }; 
}; 

只是要注意在這兩個基地和派生類中的內部類。你的情況可以忽略互斥鎖和模板的東西。