2012-02-23 11 views
25

File AhC++ undefined reference to vtable e l'eredità

#ifndef A_H_ 
#define A_H_ 

class A { 
public: 
    virtual ~A(); 
    virtual void doWork(); 
}; 

#endif 

File Child.h

#ifndef CHILD_H_ 
#define CHILD_H_ 

#include "A.h" 

class Child: public A { 
private: 
    int x,y; 
public: 
    Child(); 
    ~Child(); 
    void doWork(); 
}; 
#endif 

E Child.cpp

#include "Child.h" 

Child::Child(){ 
    x = 5; 
} 

Child::~Child(){...} 

void Child::doWork(){...}; 

Il compilatore dice che c'è un riferimento non definito a vtable per A. Ho provato molte cose diverse e ancora nessuna ha funzionato.

Il mio obiettivo è che la classe A sia un'interfaccia e separare il codice di implementazione dalle intestazioni.

+4

È necessario definire ogni funzione virtuale non pura dichiarata. Non è necessario definire una funzione non virtuale dichiarata ma non utilizzata. –

risposta

60

Perché l'errore & come risolverlo?

è necessario fornire definitions per tutte le funzioni virtuali in class A. Solo le funzioni virtuali pure non possono avere definizioni.

ossia: In class A entrambi i metodi:

virtual ~A(); 
virtual void doWork(); 

dovrebbe essere definito (dovrebbe avere un corpo)

es:

A.cpp

void A::doWork() 
{ 
} 
A::~A() 
{ 
} 

Caveat:
Se volete che il vostro class A a fungere da interfaccia (a.k.a Abstract class in C++), allora si dovrebbe fare il metodo di pura virtuale.

virtual void doWork() = 0; 

Buona Lettura:

What does it mean that the "virtual table" is an unresolved external?
When building C++, the linker says my constructors, destructors or virtual tables are undefined.

+0

Cosa intendi? – rjmarques

+0

@ user1227351: aggiornata la risposta per spiegare meglio. Leggere i collegamenti per ulteriori spiegazioni. –

+0

Avere virtual ~ A(); virtual void doWork() = 0; dà ancora errore vtable = /. Ma senza il distruttore funziona bene. Tuttavia senza di esso, se faccio qualcosa come: A * a = new Child(); cancella a; ovviamente non chiamerà Child :: ~ Child(). C'è una soluzione? – rjmarques

6

Il mio obiettivo è per un essere un'interfaccia, e per separare codice di implementazione dalle intestazioni.

In tal caso, rendono la funzione di membro come pura virtuale in classe A.

class A { 
    // ... 
    virtual void doWork() = 0; 
}; 
+0

Questo rimuove l'errore se rimuovo anche il distruttore. In tal caso, se lo faccio: A a = new Child(); elimina a; quale distruttore chiamerebbe? – rjmarques

+0

La distruzione è sempre nell'ordine inverso di costruzione. In questo caso, il distruttore di classe 'A' deve essere virtuale che impone il distruttore' Child' chiamato prima seguito dal distruttore 'A'. Se il distruttore di classe 'A' non è virtuale, il comportamento non è definito. – Mahesh

+0

Chiamerà il distruttore del bambino quando hai reso virtuale il distruttore della classe genitore. Dopodiché, il distruttore della classe genitore. – Izza

1

Assicurarsi di eliminare tutti i file "* .gch" se nessuna delle altre risposte che aiutano.