2012-02-23 17 views
25

pliku AhC++ niezdefiniowana odniesienia do vtable i dziedziczenie

#ifndef A_H_ 
#define A_H_ 

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

#endif 

pliku 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 

I Child.cpp

#include "Child.h" 

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

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

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

Kompilator mówi, że tam jest niezdefiniowana odniesienia do vtable dla A. Próbowałem wielu różnych rzeczy, ale żaden z nich nie zadziałał.

Moim celem jest, aby klasa A była interfejsem, a także oddzielny kod implementacyjny od nagłówków.

+4

Należy zdefiniować każdą zadeklarowaną nie-czystą funkcję wirtualną. Nie musisz definiować deklarowanej funkcji innej niż wirtualna, ale jej nie używasz. –

Odpowiedz

60

Dlaczego błąd & jak rozwiązać ten problem?

Musisz podać definitions dla wszystkich funkcji wirtualnych w class A. Tylko czyste funkcje wirtualne nie mogą mieć żadnych definicji.

tj W class A obu metod:

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

powinny być zdefiniowane (powinny korpus)

np

A.cpp

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

Zastrzeżenie:
Jeśli chcesz swój class A działać jako interfejs (a.k.a Abstract class w C++) następnie należy dokonać metodą czysto wirtualne.

virtual void doWork() = 0; 

dobre Przeczytaj:

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

Co masz na myśli? – rjmarques

+0

@ user1227351: Zaktualizowano odpowiedź w celu lepszego wyjaśnienia. Przeczytaj łącza, aby uzyskać dalsze wyjaśnienia. –

+0

Mając wirtualny ~ A(); virtual void doWork() = 0; nadal daje błąd vtable = /. Ale bez destruktora działa dobrze. Jednak bez niego, jeśli zrobię coś takiego: A * a = new Child(); usuń a; oczywiście nie będzie wywoływać Child :: ~ Child(). Czy jest w pobliżu praca? – rjmarques

6

Moim celem jest, aby być Interface, a do oddzielenia kodu implementacji z nagłówków.

W takim przypadku, należy funkcja członek jako czysto wirtualne w klasie A.

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

To usuwa błąd, jeśli usuwam również destruktor. W takim przypadku, jeśli mam: A a = new Child(); delete a; jaki destruktor by zadzwonił? – rjmarques

+0

Zniszczenie zawsze odbywa się w odwrotnej kolejności do konstrukcji. W tym przypadku destruktor klasy "A" musi być wirtualny, co wymusza na pierwszym miejscu destruktor 'Child', a następnie destruktor' A'. Jeśli destruktor klasy "A" nie jest wirtualny, zachowanie jest niezdefiniowane. – Mahesh

+0

Spowoduje to wywołanie destruktora potomnego, gdy wirtualny obiekt destruktora klasy nadrzędnej zostanie ustawiony. Następnie destruktor klasy nadrzędnej. – Izza

1

Upewnij się, aby usunąć wszystkie „* .gch” pliki Jeśli żadna z pozostałych odpowiedzi pomóc.

Powiązane problemy