2013-06-09 11 views
9

Non capisco perché i puntatori non siano tipi polimorfici, dal momento che possiamo utilizzare puntatori di classe base, che puntano a classi derivate, per chiamare la funzione virtuale della classe derivata. Questo suggerisce a runtime, il sistema può determinare se un puntatore è polimorfico, non è vero?tipoid per puntatori polimorfici?

(Questa è una domanda di follow-up da typeid for polymorphic types)

+0

I puntatori di classe base non puntano alle classi derivate. Stanno indicando le classi base. Questo praticamente svuota il resto delle tue conclusioni. –

+0

@VladLazarenko I puntatori non indicano affatto le classi. Puntano agli oggetti e quelli possono essere di classe base o tipo di classe derivata. Penso che sia ciò che l'OP significa (anche se, in effetti, la formulazione non è ottimale). – jogojapan

+0

Cosa sarebbe diverso se i puntatori fossero considerati tipi polimorfi? Saresti in grado di fare qualcosa che non puoi fare ora? –

risposta

3

La tua domanda soffre di un uso errato della terminologia. Il linguaggio C++ distingue molto chiaramente i puntatori stessi e gli oggetti a cui puntano questi puntatori. I tipi di puntatore non sono polimorfici. Non c'è nulla di polimorfico sul puntatore stesso. Quello che può essere veramente polimorfico è il il tipo il puntatore punta a. Quando un puntatore punta a un tipo polimorfico, spesso lo chiamiamo [informalmente] puntatore polimorfico (proprio come una scorciatoia per "un puntatore che punta a un tipo polimorfico"). Ma quando si tratta di cose come typeid, vedono le cose in modo molto formale. Per i tipi di puntatore typeid non sono mai polimorfici.

E il compilatore non determina se il puntatore è polimorfico o meno in fase di esecuzione. Questa semplice distinzione è sempre immediatamente nota al momento della compilazione. Anche in questo caso, un puntatore viene indicato come polimorfo se viene dichiarato come puntatore al tipo polimorfico.Tipo polimorfico è un tipo di classe che contiene funzioni virtuali (direttamente o indirettamente). Ovviamente, la proprietà di essere polimorfici è una proprietà puramente in fase di compilazione di un tipo.

L'unica cosa determinata in fase di esecuzione in questi casi è il tipo specifico che l'oggetto ha nel momento indicato.

+1

+1 per un uso attento della terminologia. Mi ha reso consapevole del mio uso sciatto delle parole. – jogojapan

+0

Grazie a tutti e due. Tutto ciò ha molto senso ora. :) – user2465355

9

Infatti, lo Standard (C++ 11) utilizza il concetto polimorfica tipo di classe, anziché polimorfa tipo quando descrive il comportamento di typeid:

primo luogo, qui si descrive cosa accade quando typeid viene applicato ad un lvalue di tipo classe (cioè il caso quando si fa ciò che ci si aspetta):

(§5.2.8/2) Quando typeid viene applicato a un'espressione glvalue il cui tipo è un tipo di classe polimorfico (10.3), il risultato si riferisce a un oggetto std::type_info che rappresenta il tipo dell'oggetto più derivato (1.8) (cioè , il tipo dinamico) a cui si riferisce il glvalue. [...]

Ma quando lo si applica a un puntatore (cioè non a un lvalue di tipo di classe), la regola di seguito si applica:

(§5.2.8/3) Quando typeid viene applicato a un'espressione diversa da un valore gloriato di un tipo di classe polimorfico, il risultato si riferisce a un oggetto std::type_info che rappresenta il tipo statico dell'espressione. [...]

Dice che si ottiene il tipo statico (non dinamico), cioè si ottiene il tipo dichiarato del puntatore, non il tipo di oggetto a cui punta effettivamente.

Quindi, sì, i puntatori hanno caratteristiche polimorfiche come descrivete, ma non quando si tratta del risultato di typeid.

(In realtà, tutte le loro caratteristiche polimorfiche (tra cui, in particolare, le chiamate di funzione membro polimorfi) manifestano solo se stessi quando si tratta di una sorta di dereferenziazione esplicito, sia utilizzando * o utilizzando ->,. Così si dovrebbe davvero dire che i puntatori stessi non sono polimorfici, ma solo gli oggetti che si ottengono quando li si designa.)