|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
[C++] friend function
Ho un problemino, probabilmente dovuto al fatto che ho "imparato" il C++ come uno straniero impara una lingua vivendo nel paese in cui si parla e mi manca sempre qualcosa
![]() Allora, ho una classe Thread (che devo scrivere da me perché devo fare un esame in cui devo fare un progetto che giri sia su windows che su linux) Ovviamente pthread e windows thread usano tipi di "routine" diversi.. le routine di windows ritornano un DWORD, mentre i pthread ritornano un void* Nella mia "astrazione", allora, l'exit code del thread sarà sempre un intero (che è semplicemente un campo della classe) e invece il return del thread vero e proprio (quello dell'os insomma) lo uso per distinguere "come" un thread è terminato Ora, quest'introduzione non c'entra niente, ma era solo per far capire il motivo per cui ho bisogno di una funzione "wrapper" da passare a pthread_create e CreateThread Codice:
Thread::exitcode_t Wrapper(void *arg) { struct Thread::WrapperArg *warg = (struct Thread::WrapperArg*)arg; Thread *t = warg->t; void *rarg = warg->arg; // Segnala che il thread è partito try { t->OnThreadStart(); } catch (int ex) { // Valore di ritorno che provocherà un errore nella funzione Start // così che il chiamante possa sapere che il thread non è partito. return Thread::TERMINATED; } // Semplicemente esegue la routine del thread e ne salva l'exitcode t->exitcode = t->routine(rarg); // Alla fine rimette il thread in stato inactive t->GoInactive(); t->ranonce = true; // Ritorna 0 se il thread termina normalmente return (Thread::exitcode_t)Thread::OK; } Codice:
friend Thread::exitcode_t Wrapper(void *arg); Non posso implementarla in un file .cpp esterno? La questione sarebbe che ci sono parti legate al sistema operativo (che ora ho "incapsulato" nei metodi GoInactive() e OnThreadStart(), però comunque mi sembra un po' una porcata lasciare l'implementazione nello header) |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2774
|
La funzione friend non deve specificare la classe cui appartiene, quindi invece di:
Codice:
Thread::exitcode_t Wrapper(void *arg) Codice:
exitcode_t Wrapper(void *arg) |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
no no quello c'è perché il tipo exitcode_t è un typedef che sta nella classe
è void* su linux e DWORD su win |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2774
|
Hai ragione, che scemo
![]() Ecco cosa succede a studiare un linguaggio senza scrivere neanche una linea di codice. |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Jan 2008
Messaggi: 1056
|
non ho capito bene il tuo problema.
Cioè le funzioni friend le usi dichiarandone il prototipo nella classe, e poi la puoi scrivere dove vuoi basta che la implementi. Codice:
#include <iostream> ... class Classe { friend int amica (); private: int num; }; ... int amica() { Classe c; std::cout << "Var privata: " << c.num; } |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
io ho messo nella classe:
Codice:
friend Thread::exitcode_t Wrapper(void *arg); Codice:
Thread::exitcode_t Wrapper(void *arg) { struct Thread::WrapperArg *warg = (struct Thread::WrapperArg*)arg; Thread *t = warg->t; void *rarg = warg->arg; DWORD rvalue; // Segnala che il thread è partito if (!t->sem->Signal()) { // Se c'è un errore, la funzione Start() fallirà // e questo thread verrà terminato. rvalue = Thread::TERMINATED; } else { // Semplicemente esegue la routine del thread e ne salva l'exitcode t->exitcode = t->routine(rarg); t->cterm = true; // Alla fine rimette il thread in stato inactive t->GoInactive(); rvalue = Thread::OK; } return rvalue; } e il risultato è: Codice:
1>------ Inizio compilazione: Progetto: sxl, Configurazione: Debug Win32 ------ 1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets(299,5): warning MSB8004: la directory Output non termina con una barra finale. Nell'istanza della compilazione verrà aggiunta la barra poiché è necessaria per consentire la corretta valutazione della directory Output. 1> CommonThread.cpp 1>e:\università\programmazione di sistema\progetto\src\commonthread.cpp(13): error C2248: 'sxl_mt::Thread::WrapperArg': impossibile accedere a private struct dichiarato nella classe 'sxl_mt::Thread' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(107): vedere la dichiarazione di 'sxl_mt::Thread::WrapperArg' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(33): vedere la dichiarazione di 'sxl_mt::Thread' 1>e:\università\programmazione di sistema\progetto\src\commonthread.cpp(13): error C2248: 'sxl_mt::Thread::WrapperArg': impossibile accedere a private struct dichiarato nella classe 'sxl_mt::Thread' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(107): vedere la dichiarazione di 'sxl_mt::Thread::WrapperArg' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(33): vedere la dichiarazione di 'sxl_mt::Thread' 1>e:\università\programmazione di sistema\progetto\src\commonthread.cpp(19): error C2248: 'sxl_mt::Thread::sem': impossibile accedere a private membro dichiarato nella classe 'sxl_mt::Thread' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(91): vedere la dichiarazione di 'sxl_mt::Thread::sem' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(33): vedere la dichiarazione di 'sxl_mt::Thread' 1>e:\università\programmazione di sistema\progetto\src\commonthread.cpp(24): error C2248: 'TERMINATED': impossibile accedere a private enumeratore dichiarato nella classe 'sxl_mt::Thread' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(80): vedere la dichiarazione di 'TERMINATED' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(33): vedere la dichiarazione di 'sxl_mt::Thread' 1>e:\università\programmazione di sistema\progetto\src\commonthread.cpp(31): error C2248: 'sxl_mt::Thread::exitcode': impossibile accedere a private membro dichiarato nella classe 'sxl_mt::Thread' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(69): vedere la dichiarazione di 'sxl_mt::Thread::exitcode' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(33): vedere la dichiarazione di 'sxl_mt::Thread' 1>e:\università\programmazione di sistema\progetto\src\commonthread.cpp(31): error C2248: 'sxl_mt::Thread::routine': impossibile accedere a private membro dichiarato nella classe 'sxl_mt::Thread' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(66): vedere la dichiarazione di 'sxl_mt::Thread::routine' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(33): vedere la dichiarazione di 'sxl_mt::Thread' 1>e:\università\programmazione di sistema\progetto\src\commonthread.cpp(32): error C2248: 'sxl_mt::Thread::cterm': impossibile accedere a private membro dichiarato nella classe 'sxl_mt::Thread' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(72): vedere la dichiarazione di 'sxl_mt::Thread::cterm' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(33): vedere la dichiarazione di 'sxl_mt::Thread' 1>e:\università\programmazione di sistema\progetto\src\commonthread.cpp(35): error C2248: 'sxl_mt::Thread::GoInactive': impossibile accedere a private membro dichiarato nella classe 'sxl_mt::Thread' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(97): vedere la dichiarazione di 'sxl_mt::Thread::GoInactive' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(33): vedere la dichiarazione di 'sxl_mt::Thread' 1>e:\università\programmazione di sistema\progetto\src\commonthread.cpp(36): error C2248: 'OK': impossibile accedere a private enumeratore dichiarato nella classe 'sxl_mt::Thread' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(77): vedere la dichiarazione di 'OK' 1> e:\università\programmazione di sistema\progetto\inc\thread.h(33): vedere la dichiarazione di 'sxl_mt::Thread' 2>------ Inizio compilazione: Progetto: threadtest, Configurazione: Debug Win32 ------ 2> test.cpp 2>LINK : fatal error LNK1104: impossibile aprire il file 'sxl.lib' ps: sparisce anche mettendo static al posto di friend :E una funzione public static si comporta come una friend? (su msvc sì, è così anche nello standard iso?) Ultima modifica di tuccio` : 16-01-2011 alle 01:10. |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Jan 2008
Messaggi: 1056
|
Ah eheh.
Ci scommettevo che lavori con i namespaces ![]() Ti incasinano il codice, cioè ti devi ricordare che ci sono ed ogni cosa dichiarata nel namespace ne fa parte, anche una funzione friend quindi devi cambiare ogni cosa aggiungendo il namespace, anche le varie struct ecc... Es. Codice:
sxl_mt::Thread::exitcode_t sxl_mt::Wrapper(void *arg) { Ultima modifica di Shinnok.Exor : 17-01-2011 alle 00:32. |
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
ehm, sì così in effetti va
io pensavo che quella non fosse una "dichiarazione", ma soltanto specificare che la funzione Wrapper (quindi fuori dal namespace) è una funzione friend grazie mille :v |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 02:52.