2009-10-09 76 views
3

我有一個奇怪的問題,使用多態性。 我有一個實現靜態方法的基類。由於各種原因,此方法必須是靜態的。基類還有一個純虛方法run(),它由所有擴展類實現。我需要能夠從靜態類調用run()C++中的多態性靜態方法

問題當然是靜態類沒有這個指針。該方法可以通過void *參數傳遞。我一直試圖想出一個聰明的方法來將run方法傳遞給它,但迄今爲止沒有任何工作。也嘗試將其傳遞給它。這個問題是,我將不得不實例化它,這需要擴展類的知識。這打破了多態性的全部目的。

關於如何去做這件事的任何想法?

+3

我想你的意思是「靜態方法」在第一段最後? – unwind 2009-10-09 14:44:54

+1

Ori,你反對將'this'傳遞給靜態方法,因爲「然後我必須實例化它」,但是你想調用虛擬的'run'方法。你不能在沒有實例的情況下調用一個虛擬方法,所以你將不得不實例化這個類。靜態方法不需要知道*哪個*類被實例化;正如克里斯的回答所證明的,它只是接收一個基類指針。 – 2009-10-09 15:13:11

回答

9

不要把它作爲一個void *指針,它傳遞的指針(或引用)的基類:

class BaseClass 
{ 
public: 
    static void something(BaseClass* self) { self->foo(); } 
    virtual void foo() = 0; 
}; 
3

爲什麼不傳遞對象的引用而不是方法,例如

static void func(BaseObject& o) 
{ 
    o.run(); 
} 
1

IMO,最好的辦法是擺脫靜態方法。找到一個方法,你是金。

5

這通常發生在你必須通過C API松鼠C++對象時。一個典型的例子是一個線程類。

這裏是這樣做的標準成語:

/** calls thread_func in a new thread passing it user_data as argument */ 
thrd_hdl_t c_api_thread_start(int (*thread_func)(void*), void* user_data); 

/** abstract thread base class 
* override my_thread::run to do work in another thread 
*/ 
class my_thread { 
    public: 
    my_thread() hdl_(c_api_thread_start(my_thread::thread_runner,this)) {} 
    // ... 

    private: 
    virtual int run() = 0; // we don't want this to be called from others 

    thrd_hdl_t hdl_; // whatever the C threading API uses as a thread handle 

    static int thread_runner(void* user_data) 
    { 
     my_thread* that = static_cast<my_thread*>(user_data); 
     try { 
     return that->run(); 
     } catch(...) { 
     return oh_my_an_unknown_error; 
     } 
    } 
}; 

但願幫助嗎?

+0

不錯的代碼片段,但使用'static_cast'從'void *'強制轉換爲另一個指針會更好嗎? – 2011-03-29 07:09:06

+0

@Eli:哎呀。你能做到嗎?我不知道。如果你確定,我一定會改變它。 (隨意自己改變。) – sbi 2011-03-29 09:25:11

+0

你當然*可以*做到這一點(因爲'void *'是靜態轉換 - 可以指向任何指針)。但是,你是否真的想成爲一個良好的做法。見http://stackoverflow.com/questions/310451/should-i-use-static-cast-or-reinterpret-cast-when-casting-a-void-to-whatever因爲這是你的答案,我會讓你決定:) – 2011-03-29 13:42:12