Yoninde Temat założony przez niniejszego użytkownika |
[C++] Błąd przy dziedziczeniu » 2014-11-26 19:00:34 Witam. Z książki, czy tam megatutoriala Xiona "Od zera do gier kodera" nauczyłem się dziedziczenia i poliformizmu. Chciałem zrobić program który wyświetlał by kwadraty i koła, przy pomocy SDL. W klasie bazowej kształt byłoby coś takiego jak virtual void Wyswietl i tam po prostu wyświetlanie obrazka - albo kwadratu, albo koła, z pliku PNG(Oczywiście w tych klasach pochodnych). Chciałem zrobić żeby wszystko było w vektorze z STL, czyli po kliknięciu np. P dodawało by się koło. Stworzyłem vektor < Ksztalt > v_Ksztalt i teraz jak chce zrobić coś takiego v_Ksztalt.push_back( Kolo( X i Y ) ), to wyskakuje mi błąd - undefined reference to 'vtable for Ksztalt' In function 'ZN9__gnu+cxx13new_allocatorI7KsztaltEC2ERKS2_'. Nie mam pojęcia, ale pamiętam, że kiedyś też miałem taki problem i nic z tym nie zrobiłem. Jeżeli dobrze pamiętam to klasy pochodne mają też typ klasy bazowej czy jakoś tak, to pomyślałem, że można coś takiego zrobić. Macie jakieś pomysły na rozwiązanie tego problemu? Plik z pliku Ksztalt i na dole z pliku Wyswieltacz: #ifndef KSZTALT_H_INCLUDED #define KSZTALT_H_INCLUDED
#include <string> #include <vector>
using namespace std;
class Ksztalt { protected: int X; int Y; SDL_Surface * Wyglad; public: Ksztalt( int k_X, int k_Y, string k_Wyglad ) { X = k_X; Y = k_Y; Wyglad = PM_Wczytaj( k_Wyglad ); } virtual void Wyswietl(); };
class Kolo : public Ksztalt { private: public: Kolo( int k_X, int k_Y, string k_Wyglad, int Promien ) : Ksztalt( k_X, k_Y, k_Wyglad ) { } void Wyswietl() { PM_Wyswietl( X, Y, Wyglad, Ekran ); } };
class Kwadrat : public Ksztalt { private: public: Kwadrat( int k_X, int k_Y, string k_Wyglad, int BokA, int BokB ) : Ksztalt( k_X, k_Y, k_Wyglad ) { } void Wyswietl() { PM_Wyswietl( X, Y, Wyglad, Ekran ); } };
vector < Ksztalt > v_Ksztalt;
#endif
#ifndef WYSWIETLACZ_H_INCLUDED #define WYSWIETLACZ_H_INCLUDED
#include "Ksztalt.h"
class Wyswietlacz { private: public: void Dodaj( int k_X, int k_Y, string k_Wyglad, int Promien ); void Dodaj( int k_X, int k_Y, string k_Wyglad, int BokA, int BokB ); void Usun(); void Wyswietlaj(); };
void Wyswietlacz::Dodaj( int k_X, int k_Y, string k_Wyglad, int Promien ) { v_Ksztalt.push_back( Kolo( k_X, k_Y, k_Wyglad, Promien ) ); } void Wyswietlacz::Dodaj( int k_X, int k_Y, string k_Wyglad, int BokA, int BokB ) { v_Ksztalt.push_back( Kwadrat( k_X, k_Y, k_Wyglad, BokA, BokB ) ); }
void Wyswietlacz::Usun() { v_Ksztalt.pop_back(); }
void Wyswietlacz::Wyswietlaj() { for( unsigned int i = 0; i < v_Ksztalt.size(); i++ ) { v_Ksztalt[ i ].Wyswietl(); } }
#endif
|
|
unkn9wn |
» 2014-11-26 19:18:44 "nauczyłem się dziedziczenia i poliformizmu"
To sprawdź jeszcze enkapsulację :) i ten vector obiektów wstaw jako private u Wyswietlacza
|
|
oputyk |
» 2014-11-26 19:21:00 vector < Ksztalt > v_Ksztalt; zamień na vector < Ksztalt * > v_Ksztalt; oraz do vector'a wrzucaj obiekty alokowane dynamicznie i nie zapomnij na koniec ich usunąć. PS: Oraz to co kolega wyżej napisał... |
|
NopeDotAvi |
» 2014-11-26 19:22:33 używasz polimorfizmu, więc zamiast vector < Ksztalt > v_Ksztalt; użyj smart-pointerów (od c++11 code blocks wspiera c++11 tylko musisz w opcjach znaleźć). czyli tak: #include <memory> #include <vector>
std::vector < std::unique_ptr < Ksztalt > > v_Ksztalt;
powinno pomóc. |
|
Yoninde Temat założony przez niniejszego użytkownika |
» 2014-11-26 19:45:30 Zrobiłem to na wskaźnikach i dalej nic. Teraz tylko, zamiast dwóch takich samych błędów (nie pisze która linia, ale myślę, że jeden błąd na jedno Dodaj()) jest tylko jeden błąd. Jak usunę oba Dodaj, to błąd znika. #include "Ksztalt.h"
class Wyswietlacz { private: vector < Ksztalt * > v_Ksztalt; public: void Dodaj( int k_X, int k_Y, string k_Wyglad, int Promien ); void Dodaj( int k_X, int k_Y, string k_Wyglad, int BokA, int BokB ); void Usun(); void Wyswietlaj(); };
void Wyswietlacz::Dodaj( int k_X, int k_Y, string k_Wyglad, int Promien ) { Ksztalt * w_Kolo = new Kolo( k_X, k_Y, k_Wyglad, Promien ); v_Ksztalt.push_back( w_Kolo ); delete w_Kolo; } void Wyswietlacz::Dodaj( int k_X, int k_Y, string k_Wyglad, int BokA, int BokB ) { Ksztalt * w_Kwadrat = new Kwadrat( k_X, k_Y, k_Wyglad, BokA, BokB ); v_Ksztalt.push_back( w_Kwadrat ); delete w_Kwadrat; }
void Wyswietlacz::Usun() { v_Ksztalt.pop_back(); }
void Wyswietlacz::Wyswietlaj() { for( unsigned int i = 0; i < v_Ksztalt.size(); i++ ) { v_Ksztalt[ i ]->Wyswietl(); } } |
|
maly |
» 2014-11-26 20:11:25 Nie ma to jak konkretna informacja. class Ksztalt { virtual void Wyswietl() = 0; }; |
|
Yoninde Temat założony przez niniejszego użytkownika |
» 2014-11-26 20:17:25 Boże, zapomniałem o tym... Dzięki wielkie. A co do tego błędu, to jest to ten sam co w pierwszym poście na samej górze. Dzięki wielkie jeszcze raz. |
|
« 1 » |