PDA

View Full Version : [C++] Warning che non capisco ...


trallallero
20-02-2009, 15:42
Perchè questa linea mi da un warning ?
LLUnit* pUnit = m_UnitHandler->GetEntity("AUDIO");

il warning:
src/LLEngine.cpp:345: warning: invalid conversion from ‘LLBaseEntity*’ to ‘LLUnit*’

La funzione è così:
LLBaseEntity* GetEntity (string sName) { return SingleTone->GetEntityBase(SingleTone->GetEntityIdBase(sName)); }

e LLUnit deriva da LLBaseEntity:
class LLUnit : public LLBaseEntity

Vabbè che è venerdì e son fuso ma mi sfugge qualcosa :wtf:

wingman87
20-02-2009, 15:51
Se LLUnit deriva da LLBaseEntity devi fare un cast per fare quell'assegnamento (sempre che sia lecito).

trallallero
20-02-2009, 15:54
Se LLUnit deriva da LLBaseEntity devi fare un cast per fare quell'assegnamento (sempre che sia lecito).

Ma perchè, scusa ? io vorrei proprio evitare un reinterpret_cast che bello non è

wingman87
20-02-2009, 16:03
Purtroppo di C++ non so niente, quindi non so dirti quale tipo di cast è necessario, però così mi sembra normale il warning, ti sta dicendo solo che se metti dei frutti in un cesto di mele devi assicurarti che i frutti siano proprio mele.

Se mi sto sbagliando scusami, non voglio sembrare saccente, provo solo a dare una mano.

trallallero
20-02-2009, 16:15
Purtroppo di C++ non so niente, quindi non so dirti quale tipo di cast è necessario, però così mi sembra normale il warning, ti sta dicendo solo che se metti dei frutti in un cesto di mele devi assicurarti che i frutti siano proprio mele.

Se mi sto sbagliando scusami, non voglio sembrare saccente, provo solo a dare una mano.

Figurati, a quest'ora di venerdì anche i consigli di un panettiere potrebbero servire :D

grazie

cionci
20-02-2009, 18:58
Il cast implicito da LLBaseEntity * a LLUnit * non è lecito, devi farlo esplicito. E' illecito perché non hai alcuna garanzia che il puntatore ritornato sia un puntatore a LLUnit.
Al contrario da LLUnit * a LLBaseEntity * è lecito.

trallallero
20-02-2009, 20:54
Il cast implicito da LLBaseEntity * a LLUnit * non è lecito, devi farlo esplicito. E' illecito perché non hai alcuna garanzia che il puntatore ritornato sia un puntatore a LLUnit.
Al contrario da LLUnit * a LLBaseEntity * è lecito.

Mi hanno rotto le palle (amichevolmente) perchè ho usato qualche reinterpret_cast nel progetto.

Secondo te è "sbagliata" (diciamo criticabile) un'istruzione del genere ?
LLUnit* pUnit = reinterpret_cast<LLUnit*>(m_UnitHandler->GetEntity("AUDIO"));

Sto usando m_UnitHandler che è di tipo LLUnitHandler quindi so per certo che contiene LLUnit e basta.
LLUnitHandler deriva da LLBaseHandler che contiene praticamente tutte le funzioni di handling delle entità tranne un paio di funzioni astratte che vengono implementate nei vari handlers derivati.

Boh, secondo me va bene ... ok, reinterpret_cast è una forzatura ma so quello che faccio, non forzo un puntatatore ad una classe a caso.

Che poi LLUnit è astratta e chiamando il suo metodo "pure virtual" ExecuteLogic, sfrutto la potenza del polimorfismo.
Per me è elegante.

cionci
20-02-2009, 21:01
Usa un dynamic_cast ;)

trallallero
20-02-2009, 21:07
Usa un dynamic_cast ;)

Mai usato ... si vede che vengo dal C, vè ? :stordita:

ok grazie, leggerò qualcosa sui cast.

cionci
21-02-2009, 08:33
Mai usato ... si vede che vengo dal C, vè ? :stordita:

ok grazie, leggerò qualcosa sui cast.
dynamic_cast si usa proprio quando devi fare un cast da una classe base ad una derivata da questa.
http://www.cplusplus.com/doc/tutorial/typecasting.html

Attenzione comunque alla nota scritta lì. E' da verificare nel tuo caso.

trallallero
25-02-2009, 13:01
dynamic_cast si usa proprio quando devi fare un cast da una classe base ad una derivata da questa.
http://www.cplusplus.com/doc/tutorial/typecasting.html

Attenzione comunque alla nota scritta lì. E' da verificare nel tuo caso.

Di nuovo vedo solo ora che hai scritto in questo 3d (perchè ci stavo per scrivere io).
Ma non dovrebbe essere in grassetto il link al 3d quando qualcuno scrive qualcosa di nuovo ? :wtf:

Vabbè, grazie del link.

Mi da errore in questo caso, cerco di castare da primo a secondo:
‘void (class LLPanelSEM80_90::*)(class LLMsg_t&, class LLMessage*, struct LL_ACTION_SIGNAL&)’
‘void (class LLPanel::*) (class LLMsg_t&, class LLMessage*, struct LL_ACTION_SIGNAL&)’

Ma non capisco perchè, LLPanelSEM80_90 è una derivata di LLPanel :boh:

Errore:
src/Panels/LLPanelSEM80_90.cpp:40: error: cannot dynamic_cast ‘&LLPanelSEM80_90::Button_Power’ (of type ‘void (class LLPanelSEM80_90::*)(class LLMsg_t&, class LLMessage*, struct LL_ACTION_SIGNAL&)’) to type ‘void (class LLPanel::*)(class LLMsg_t&, class LLMessage*, struct LL_ACTION_SIGNAL&)’ (target is not pointer or reference)

Ma non è vero perchè il target è un array di puntatori a metodi della classe LLPanelSEM80_90:
typedef void (LLPanel::*PanelLogicFunctions)(LOGIC_FUNCTIONS_PARAMS);
...
PanelLogicFunctions m_Functions[SEM80_90_DEV_FUNCTIONS]; //!< Panels' devices' functions
...
m_Functions[0] = dynamic_cast<PanelLogicFunctions>(&LLPanelSEM80_90::Button_Power);

cionci
25-02-2009, 18:57
Scusa, ma che c'entra il cast di un puntatore a funzione ? Questo non è un cast da un tipo derivato alla classe base. Quei due tipi non sono derivati l'uno dall'altro.

Sinceramente con la programmazione ad oggetti non mi sono trovato molto spesso ad operare con puntatori a funzioni. Probabilmente li puoi evitare.

trallallero
25-02-2009, 21:10
Scusa, ma che c'entra il cast di un puntatore a funzione ? Questo non è un cast da un tipo derivato alla classe base. Quei due tipi non sono derivati l'uno dall'altro.
:doh:

Son fuso ... fortuna che dopo il progetto mi faccio 2 settimane di vacanza.

Sinceramente con la programmazione ad oggetti non mi sono trovato molto spesso ad operare con puntatori a funzioni. Probabilmente li puoi evitare.

Lo so, ma io vengo dal C e questo è stato il mio primo progetto interamente in C++ dove ho dovuto sia implemantare che fare tutto il design.
E mi ricordo anche che mi hai suggerito di usare i pattern invece dei puntatori a metodo (ho ancora il 3d per il futuro ;)) ma avevo poco tempo ed ho preferito usare qualcosa che conosco bene.

Comunque non è male come design: ho matrici di pulsanti, lo stesso prototipo di funzione (tipo OnClick) per ogni pulsante e quindi una "matrice" (in realtà array) di puntatori a metodi, uno per ogni pulsante.

edit: scusa ma è da molto che volevo chiedertelo: chi è il chitarrista nel tuo avatar ?

cionci
26-02-2009, 07:59
edit: scusa ma è da molto che volevo chiedertelo: chi è il chitarrista nel tuo avatar ?
Chuck Schuldiner ;)

trallallero
26-02-2009, 08:19
Chuck Schuldiner ;)

Sei un metallaro :D

cionci
26-02-2009, 08:23
Sei un metallaro :D
:yeah:

trallallero
26-02-2009, 08:32
:yeah:

Io ogni sera suono Joe Satriani, conosci ?
ho appena finfito di imparare "satch boogie".

Ok, non è metallo, ma non è certo musica pop :D

cionci
26-02-2009, 08:43
Non lo conosco bene, ma le poche cose che ho ascoltato mi sono piaciute. Se sai suonare Satriani allora sai suonare molto bene :D

trallallero
26-02-2009, 09:02
Non lo conosco bene, ma le poche cose che ho ascoltato mi sono piaciute. Se sai suonare Satriani allora sai suonare molto bene :D

Beh, è stato il mio lavoro fino a 28 anni prima di diventare informatico quindi diciamo che me la cavo (certo che prima suonavo 8 ore al giorno, adesso solo 1-2).

Quì suono The Extremist http://www.youtube.com/watch?v=tyqQJi1iWa8
Anche se è di un pò di tempo fa, adesso l'ho migliorata.

Vorrei arrivare ad almeno 12-15 pezzi per fare qualche serata ma sono solo a 8 :coffee:

Vabbè, un pelino OT :fiufiu:

cionci
26-02-2009, 09:14
E stica :eek: :ave:

trallallero
26-02-2009, 09:23
E stica :eek: :ave:

Grazie :cool:

Se suoni anche tu, ho trovato un argomento sul quale posso dare io dei suggerimenti a te :D

cionci
26-02-2009, 09:27
Se suoni anche tu, ho trovato un argomento sul quale posso dare io dei suggerimenti a te :D
Suonavo, ho ripreso in mano la chitarra da qualche giorno...ma sono davvero asino :D

trallallero
26-02-2009, 09:34
Suonavo, ho ripreso in mano la chitarra da qualche giorno...ma sono davvero asino :D

C'é sempre tempo per imparare ... però c'è niente da fare, le cose imparate da piccoli rimangono scolpite dentro di noi.

trallallero
27-02-2009, 09:24
Ho dovuto, in certi punti, rimettere reinterpret_cast perchè il dynamic_cast mi dava null pointer.

Per esempio questa:
LLPanelAE* pPanel = dynamic_cast<LLPanelAE*>LLPanelHandler::GetEntity(msg.getPanelId()));
fallisce ...

dove LLPanelAE è una derivata di LLPanel
LLPanelHandler deriva da LLBaseHandler che ha la funzione GetEntity che restituisce un pointer a LLBaseEntity che è la prima class base astratta.
LLPanelHandler è una singletone con metodi static perchè deve essere accessibile da tutte le Unit senza dover creare un'istanza, quindi il metodo è così:
static LLPanel* GetEntity(LLEntityId Id)
{
return dynamic_cast<LLPanel*>(SingleTone->GetEntityBase(Id));
}


C'è un modo per sapere perchè il dynamic_cast fallisce ?
Ho paura che sia colpa della LLBaseEntity ...


http://lh3.ggpht.com/_HH5byQu0gx4/R8_DP9xMhMI/AAAAAAAAAD8/037QDpzQnkg/s800/LL.jpg

trallallero
27-02-2009, 11:43
Invece è giusto! dipende solo dall'id del Panel (msg.getPanelId())

Quindi se il dynamic_cast mi da 0 vuol dire che sto forzando un PanelX ad essere un PanelY ... :stordita:

Quindi col reinterpret_cast funziona "per culo" :asd:

cionci
27-02-2009, 11:52
Invece è giusto! dipende solo dall'id del Panel (msg.getPanelId())

Quindi se il dynamic_cast mi da 0 vuol dire che sto forzando un PanelX ad essere un PanelY ... :stordita:
Già :D

trallallero
27-02-2009, 12:00
Già :D

Si ma adesso ricordo: a metà progetto è uscita una storia nuova che mi ha obbligato a forzare il PanelAE a comportarsi come il PanelIntercom e solo in certe occasioni.

Quindi non è colpa mia :O




:fiufiu:

cionci
27-02-2009, 12:04
Che casino :doh: :asd:

trallallero
27-02-2009, 12:18
Tu ridi ma non puoi immaginare la complessità di 'sta logica!
- se non è in modalità Teacher Communication
- se il tipo sta parlando ma nessuno parla con lui
- se uno tenta di parlare mentre il carro armato esce dalla zona coperta dalla radio
- se la frequenza viene cambiata mentre parlano
- se aumenta la distanza del militare devo aumentare il rumore di fondo
- se il teacher preme il pulsante "ALL" TUTTE le comunicazioni vanno chiuse perchè lui deve parlare a tutti e poi vanno ripristinate
- ... (altre 6000 "se")

Ho appena finito la gestione delle distanze dei componenti dell'esercitazione per la percentuale di rumore di fondo e adesso hanno voluto anche simulare la rottura delle radio ! :muro:

Ma tutto specificato all'inizio no, eh ?