undefined reference to `vtable for nazwa_klasy' -> baardzo wkurzające

0

Mam 2 klasy: klasaA oraz klasaB, klasaB dziedziczy po klasieA. Mam kilka plików: klasaA.h, klasaB.h, klasaB.cpp oraz main.cpp. W klasie A mam metodę czysto wirtualną oraz wirtualny konstruktor. Jednak przy kompilacji tego wszystkiego dostaję takie błędy:

/tmp/ccqoGdHx.o: In function `main':
main.cpp:(.text+0x24): undefined reference to `klasaB::napisz()'
/tmp/ccqoGdHx.o: In function `klasaB::klasaB()':
main.cpp:(.text._ZN6klasaBC1Ev[klasaB::klasaB()]+0x12): undefined reference to `vtable for klasaB'
/tmp/ccqoGdHx.o: In function `klasaB::~klasaB()':
main.cpp:(.text._ZN6klasaBD1Ev[klasaB::~klasaB()]+0x7): undefined reference to `vtable for klasaB'
collect2: ld returned 1 exit status

To moje pliki:

#ifndef __KLASAA_H__
#define __KLASA_H__

class klasaA{
        public:
                virtual void napisz() = 0;
                virtual ~klasaA(){};
};

#endif
#ifndef __KLASAB_H__
#define __KLASAB_H__

#include "klasaA.h"

class klasaB : public klasaA{
        public:
                void napisz();
                virtual ~klasaB(){};
};

#endif
#include "klasaB.h"
#include <iostream>
using namespace std;

void klasaB::napisz(){
        cout << "hej" << endl;
}
#include "klasaB.h"

int main(){

        klasaB b;
        b.napisz();
        return 0;
}

Kompilator to gcc, używam ubuntu. Błagam pomóżcie, bo już nie mam pojęcia, co z tym zrobić (proszę nie podawać rozwiązań typu umieść to wszystko w 1 pliku, bo muszę mieć podział na pliki ...)

Zapomniałem dodać, że kompiluję tak: g++ main.cpp -o main - a literówka w kodzie (przez omyłkę napisałem #define KLASA_H zamiast KLASAA_H i tak nic nie zmienia)

0
bogdan napisał(a)

mam metodę czysto wirtualną oraz wirtualny konstruktor.

Nie ma w c++ czegoś takiego jak wirtualny konstruktor. Masz wirtualny destruktor, dodatkowo niepotrzebnie definiujesz go jako virtual w klasie pochodnej, bo wystarczy, że jest taki w klasie bazowej. Nie pisz średników za klamrami definicji metod/funkcji bo straszne jest. Nie działa ci bo źle kompilujesz.
Jeśli twój projekt składa się przykładowo z plików: klasaA.cpp, klasaA.h, klasaB.cpp, klasaB.h, main.cpp to kompilujesz przykładowo tak: g++ -o test main.cpp klasaA.h klasaA.cpp klasaB.h klasaB.cpp . Nie wystarczy sam main.

0

A co do konstruktora wirtualnego to wiem :p widocznie za szybko pisałem i wyszło mi takie cudo jak wirtualny konstruktor. Dziwne - zawsze tak kompilowałem i nie miałem problemów. Zaraz przetestuję Twój sposób.

0

Dzięki! Teraz już wszystko działa :) Taki głupi błąd, a nigdzie nie mogłem znaleźć odpowiedzi. Mam jeszcze jedno pytanie : jeśli mam sporo plików do kompilacji, to nie ma jakiegoś szybszego sposobu, tylko trzeba te wszystkie ich nazwy wklepywać po g++ -o test (oczywiście w sytacji, gdy w katalogu są tylko pliki do kompilacji tego jednego programu)?

0

@Matek, a co Ci da kompilowanie nagłówków? Z resztą kompilować może pliki osobno, ale linkowanie musi przeprowadzić mając już wszystkie obiekty.
@bogdan, w pierwszym pliku powinno być raczej #define __KLASAA_H__

Ogólnie przy podziale na parę plików (przyjmując konwekcję nazewniczą od kolegi wyżej) piszesz sobie ładnie Makefile:

CXX=g++
CFLAGS=-c -Wall    # i inne flagi jakie potrzebujesz
LDFLAGS=              # flagi linkowania

all: main

main:  klasaA.o klasaB.o main.o
  $(CXX) $(LDFLAGS) $< -o $@

main.o: main.cpp
  $(CXX) $(CFLAGS) $< -o $@

klasaA.o: klasaA.cpp
  $(CXX) $(CFLAGS) $< -o $@

klasaB.o: klasaB.cpp
  $(CXX) $(CFLAGS) $< -o $@
0

@winerfresh: bardzo ciekawy, ale trochę przerażający na początek sposób ;) i nie wszystko jest w nim dla mnie zrozumiałe - można gdzieś poczytać o tych flagach, o któych piszesz? (np. -Wall, bo do tej pory kompilowałem wszystko tylko tak, jak pisałem wcześniej).

0

Ah, i jeszcze pytanie : jak dalej postępować z takim makefilem? Ubuntu znam jeszcze dosyć słabo, stąd moje pytania. Wcześniej pisałem wszystko na Code::blocks na Win i nie miałem takich problemów ;)

0

Flagi są opisane w podręczniku (man gcc). Wpisujesz w konsoli make all.

0

a jakiś dokładny opis tego makefila (tzn. jak go tworzyć, co oznaczją poszczególne linijki pliku)? Co i jak i dlaczego akurat tak? ;) Niektóre rzeczy z niego rozumiem (z makefila), ale nie wszystkie. A chciałbym się dowiedzieć, bo sposób naprawdę elegancki, a głupio używać czegoś, jak się nie wie, jak dokładnie to działa.

1 użytkowników online, w tym zalogowanych: 0, gości: 1