2012-02-06 10 views
6

L'indice vptr dovrebbe visualizzare tutte le funzioni virtuali, ma nel mio caso solo 2 delle 3 funzioni virtuali vengono visualizzate.La funzione virtuale non è elencata nel vptr

sto fornendo il codice completo e gli screenshot qui sotto: -

ClassHeader.h

#include <iostream> 
using namespace std; 

// Employee Class 

class Employee 
{ 
    public : 
int salary ; 
Employee(){cout << "Inside CTOR" << endl;} 

virtual ~Employee() {cout << "Inside DTOR" << endl;} 

virtual void pay(){cout << "Employee" << endl;} 
}; 

// Manager Class 

class Manager : public Employee 
{ 
    public : 

virtual void pay(){cout<< "Manager pay" << endl;} 
virtual void Rank(){cout << "Manager Rank" << endl;} 
}; 

// JuniorManager Class 
class JuniorManager : public Manager 
{ 
    public : 

virtual void pay(){cout<< "JuniorManager pay" << endl;} 
virtual void Rank(){cout << "JuniorManager Rank" << endl;} 
}; 

Main.cpp

#include "ClassHeader.h" 

void main() 
{ 
    Manager *p = new Manager(); 

p->pay(); 
p->Rank(); 

p = new JuniorManager(); 
p->Rank(); 

Employee *pE = dynamic_cast<Employee*>(p); 
pE->pay(); 

} 

La classe Manager ha due funzioni virtuali, pagare e Classifica, ma solo la paga viene mostrata nella vptr.

Qualcuno può dirmi, perché Rank non viene visualizzato, anche se la sua funzione virtuale.

Sto utilizzando Visual Studio 2008 e con gli ultimi aggiornamenti, su Windows 7 a 64 bit.

enter image description here

JuniorManager Debugger Schermata

Non mostra le funzioni virtuali sia. Si prega di vedere l'immagine qui sotto.

enter image description here

+0

Visual Studio ci dice _Base class di 'Manager' 'Employee'ha 2 funzioni virtuali: destructor e pay_. Cosa c'è che non va? – Lol4t0

+0

_void_ main()? C++ consente int main() e int main (int, char **). – Collin

risposta

2

Se si ispezionare la classe come un impiegato, dal momento che la classe non ha Rank(), non mostrerà il Rank() nella vtable. Lo screenshot mostra il contenuto della classe Employee.

"Yup, il debugger non dispone di informazioni sufficienti per dire tipo quanto tempo l'array è. Quindi viene visualizzato solo il primo elemento a meno che non ignorata."

http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/23d4e48e-520e-45b4-8c2f-65c11946d75d

+2

Sto dichiarando un puntatore a un Manager, non a un Dipendente. Si prega di consultare il codice completo. –

+0

Ma la finestra di ispezione mostra la classe Employee. Almeno il contenuto della tabella è corretto in questo senso. – perreal

+0

È vero? A quanto ho capito, in generale, ogni istanza ha un solo vtable, che viene fuso dalla sua catena di ereditarietà - per questo vediamo 'const Manager :: 'vftable'' e non' const Employee ::' vftable''. Non sono un guru di Visual Studio, ma nasconderebbe contemporaneamente le funzioni virtuali mostrando il tipo corretto? – Matt

1

Forse questo è dovuto al fatto Manager è derivante da dipendente, ma dipendente non avere un metodo Rank. Quindi quando un oggetto Manager chiama Rank() non avrà mai bisogno di essere nella tabella virtuale. Scommetto che se istanziate un Rank JuniorManager sarà nel vtbl.

Per ulteriori chiarimenti, consultare Does C++ virtual function call on derived object go through vtable? ma credo che questo sia il motivo corretto.

1

Credo che sia perché non ci sono overrider possibili della funzione Rank nella catena di ereditarietà di Manager, anche se è virtuale. In altre parole, penso che la tua classe debba sapere dove le funzioni virtuali sovrascrivibili devono inviare correttamente la chiamata alla funzione, il che significa che l'implementazione deve memorizzare i puntatori alle funzioni virtuali. Se nessuno può ignorare le funzioni, non c'è ambiguità nell'invio e nessuna ragione per mantenere un altro puntatore nel vtable.

Si dovrebbe essere in grado di verificare facendo questo stesso esercizio esattamente con l'istanza JuniorManager: da quando abbiamo bisogno di mantenere un puntatore a funzione di Rank del Gestore nei casi JuniorManager, dal momento che abbiamo un sovrascritto funzione Rank, dovremmo vedere il puntatore virtuale nel vtable di JuniorManager.

Ora sono curioso.Potresti controllare questo per noi e riferire?

0

Penso che quello che stiamo vedendo qui è una strana stranezza di Visual Studio che non riesco a spiegare.

Ho copiato il codice in Visual Studio per vedere cosa sta succedendo e ho anche provato ad aggiungere:

JuniorManager *p1 = new JuniorManager();

p1 è dimostrato di essere un JuniorManager che è una sottoclasse di Manager, che è una sottoclasse di Dipendente.

In tutti i casi il debugger è pienamente consapevole del tipo esatto statico delle variabili puntatore e il tipo dinamico esatto degli oggetti si punta e il tipo esatto di vtable e il tipo esatto delle voci nella vtable. Tuttavia, il vtable è visibile solo nel debugger come parte della classe base (Employee) e per qualche motivo vengono mostrate solo le voci conosciute per la classe base.

Sarebbe molto più bello se mostrasse anche il resto delle voci.

0

Cambia proprietà linker Linker-> Ottimizzazione-> Riferimenti a/OPT: NOREF. Visual Studio rimuove i riferimenti a funzioni non utilizzate (non definite). Con questo switch linker non rimuove tali riferimenti.

Problemi correlati