2009-10-09 77 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