2011-01-12 22 views
5

Come dice il titolo. Quello che segue è il mio scheletro di codice.eseguire thread della funzione membro della classe in C++

class CLASS 
{ 
public: 
    void A(); 
private: 
    DWORD WINAPI B(LPVOID); 
}; 

void CLASS::A() 
{ 
    DWORD (WINAPI CLASS::*thread)(LPVOID) = &CLASS::B; 
    ... 
    CreateThread(NULL, 0, thread, &arg, 0, NULL); 
    ... 
} 

la funzione B richiede le variabili membro CLASS.
Ma ho un codice di errore quando ho compilato questo.
È "impossibile convertire l'argomento 3 da" DWORD (__stdcall CLASS :: *) (LPVOID) "a" LPTHREAD_START_ROUTINE "" o qualcosa del genere.
Non so se è lo stesso in ambiente inglese.

qualcuno può aiutare per favore?

risposta

3

È necessario rendere questa funzione membro static.

Il problema qui è che ogni funzione membro non statico ha un parametro implicito this e questo è in effetti ciò che il compilatore sta tentando di dirti: la tua funzione membro nin statico ha una firma diversa da quella che ti aspettavi.

Vedere anche this answer to a closely related question.

+3

E prima che inizi la OP ottenere idee intelligenti - i puntatori di funzioni dei membri della classe non statici sono * strani *. Non solo le convenzioni di chiamata differiscono da un semplice 'func (classname * this, ...)', la _pointer representation_ è strana - in alcuni casi i puntatori di funzione dei membri della classe possono diventare 2x della dimensione di un normale puntatore a funzione, quindi non pensare nemmeno a forzare il cast :) – bdonlan

10

È necessario definire la funzione di richiamata come funzione static se è una funzione membro!


Design migliore: definire una classe riutilizzabile!

Dal mio previous answer: (con poche modifiche)

Ancora meglio sarebbe definire una classe riutilizzabilecon pura funzione virtuale run() essere attuata dai derivati ​​filo classi. Ecco come dovrebbe essere progettato:

//runnable is reusable class. All thread classes must derive from it! 
class runnable 
{ 
public: 
    virtual ~runnable() {} 
    static DWORD WINAPI run_thread(LPVOID args) 
    { 
     runnable *prunnable = static_cast<runnable*>(args); 
     return prunnable->run(); 
    } 
protected: 
    virtual DWORD run() = 0; //derived class must implement this! 
}; 

class Thread : public runnable //derived from runnable! 
{ 
public: 
    void newthread() 
    { 
     CreateThread(NULL, 0, &runnable::run_thread, this, 0, NULL); 
    } 
protected: 
    DWORD run() //implementing the virtual function! 
    { 
     /*.....your thread execution code.....*/ 
    } 
} 
+0

Vorrei utilizzare un modello piuttosto che l'ereditarietà di runtime. Ma l'idea generale è corretta. – Puppy

+0

@DeadMG: intendi CRTP? – Nawaz

+0

+1, ma renderei il metodo 'run' protetto. –

11

Scherzi a parte, l'uso std :: filo (o boost :: discussione se il compilatore non supporta ancora):

class CLASS 
{ 
public: 
    void A(); 
private: 
    void B(your args go here); 
}; 

void CLASS::A() 
{ 
    boost::thread(&CLASS::B, this, your args go here); 
} 
+2

+1. Sì, sicuramente andare con std ::/boost :: thread. Inoltre, non è nemmeno necessario associare: 'boost :: thread t (& CLASS :: B, this, your args se c'è qualcuno che va qui);'. Così semplice. – usta

+0

@usta: grazie! fisso. – ybungalobill

Problemi correlati