2013-03-07 13 views
7

Omówienie klas itp. Mojego interfejsu!C++: błąd LNK: nierozwiązany symbol zewnętrzny, wynikający z funkcji wirtualnych

Animal.H:

class Animal 
{ 
public: 
    virtual void walk(); 
} 

Animals.CPP

= Puste

Cow.H:

class Cow : public Animal 
{ 
public: 
    virtual void walk(); 
} 

W tym miejscu powinno być oczywiste, że funkcja jest pobierana z klasy, skąd pochodzi od prawej? (e.a. Animal ..) kiedy nie zdefiniowałbym funkcji chodzić, powinien powiedzieć, że powinienem zdefiniować to dobrze ...?

Cow.CPP:

void Cow::walk() 
{ 
    //do something specific for cow 
} 

SomeOtherClass.H

namespace SomeNamespace 
{ 
    void LetAnimalWalk(); 
} 

SomeOtherClass.CPP

Cow myCow; 
namespace SomeNamespace 
{ 
    void LetAnimalWalk() 
    { 
     myCow.walk(); 
    } 
} 

Thi Czy powinno działać poprawnie? ... to znaczy przestrzeń nazw, rzeczy "Klasy :: ..."? i sposób, w jaki dziedziczę i używam interfejsu?

ponieważ w ten sposób mogę uzyskać z każdej funkcji zrobiłem z interfejsu, więc każda funkcja wirtualnego daje mi następujący błąd:

SomeOtherClass.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall Cow::Walk (...etc etc...) referenced in function "void __cdecl SomeNamespace::LetAnimalWalk() (...etc etc...) 

Czy ktoś wie, co robię źle, co robię znaleźć głównie jest to, że oznacza to, że nie zostały uznane za prawo funkcyjny (gdzieś w Cow.cpp ??)

z góry dzięki chłopaki

+2

Czy 'myCow.Walk();' literówka? Ta funkcja nazywa się 'walk()' (małe litery) –

+0

O tak, to jest typo .. Właśnie napisałem to wszystko ręcznie tutaj, prawdziwa klasa jest czymś trudnym, ale pomyślałem, że może być zbyt specyficzna może dla stackoverflow .. .! –

+0

@AndyProwl próbowałeś mi pomóc również wczoraj, na to samo pytanie, które było bardziej szczegółowe Andy .. odpowiedziałem, ale nie sądzę, że przeczytałeś to ... mój drugi post był: http://stackoverflow.com/ pytania/15226986/c-lnk-error-2019-nierozwiązany zewnętrzny-symbol-virtual-errors-because-of-an-inter # comment21465084_15226986 –

Odpowiedz

9
class Animal 
{ 
public: 
    virtual void walk(); 
} 

trzeba zdefiniować tę funkcję lub dokonać to czysty wirtualny.

+0

Ale jest wirtualny prawda? Więc kiedy robię krowy :: chodź ... definiuję to .. czy? –

+0

Jeśli funkcja klasy podstawowej nie jest czysto wirtualna, musisz ją zdefiniować również w klasie zwierząt. Jeśli jest to czysto wirtualne w Animal, po prostu musisz zdefiniować je w Krowie. Również funkcje wirtualne są zwykle używane ze wskaźnikami do klas bazowych, np. 'Animal * animal = new Cow(); animal-> walk(); 'który nazwałby funkcję chodzenia w klasie krów. –

+0

Hmm, próbowałem tego teraz ...! Z pewnością lepiej jest go używać w ten sposób, ale nadal pozostają te same błędy ...... –

4

Kiedy masz wirtualny funkcji, które nie chcą, aby zdefiniować w klasie bazowej, trzeba zrobić to streszczenie, odbywa się to przy użyciu następującej składni:

class Animal 
{ 
public: 
    virtual void walk() = 0; 
} 

Bez tego dostaniesz błąd, jeśli nie jest zdefiniowany, a dzięki temu otrzymasz błąd, jeśli jakakolwiek klasa pochodna go nie definiuje.

+0

Ahh mój zły, mam nawet to ...! więc było już czysto wirtualne ... ale nadal ma ten sam błąd! –

2

odbyć funkcję w klasie podstawowej czystej wirtualnego:

class Animal 
{ 
    public: 
     virtual void walk() = 0; 
} 

lub zdefiniować trywialne realizacji:

void Animal::walk() 
{ 
    return; // could also throw an exception here 
} 
+0

Nawet zdefiniowałem to tak jak powiedziałeś, ta trywialna implementacja (uczyniłem to czystym wirtualnym, zdefiniowałem implementację, zrobiłem obie jednocześnie ... ale mój błąd pozostaje ten sam –

+0

Tak, widzę, że zmodyfikowałeś pytanie Niestety, Twój kod jest oczywiście uproszczony, więc zakładam, że masz wszystkie brakujące dyrektywy '# include' (w przeciwnym razie powinieneś dostać błąd przed etapem łącza). jesteś pewien, że 'Cow.cpp' jest częścią twojego projektu lub makefile? – jerry

+0

Używam VS2012 ... i rzeczywiście, włącza i nie wstawiłem tutaj w pytaniu! Ehm, Cow.cpp o ile widziałem jest częścią rozwiązania .. przejdę na pewno sprawdzić, czy rzeczywiście Tak, mój VS2012, po prostu mówi, że jest zawarty w projekcie ...!: \ –

1

chów zwierząt * = nowy krowy(); animal-> walk();

Krowa myCow NIE działa oczywiście!

+0

Wywołanie 'walk()' bezpośrednio na obiekcie 'Cow' w rzeczywistości shou ld pracy (nie daje błąd linker).Powodem, dla którego zwykle nazywamy funkcję wirtualną za pomocą wskaźnika, jest upewnienie się, że faktycznie jest nazywana wirtualnie (napisałem szybki przykład na stronie http://ideone.com/UteSxT). Fakt, że to naprawiło twój problem, mówi mi, że dzieje się coś jeszcze. – jerry