Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Błąd przy dziedziczeniu

Ostatnio zmodyfikowano 2014-11-26 20:17
Autor Wiadomość
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:

C/C++
#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 // KSZTALT_H_INCLUDED






//Nie wiem jak zrobić, żeby były dwa inne kody źródłowe
//Tutaj jest klasa wyświetlacza

#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 // WYSWIETLACZ_H_INCLUDED
P-121458
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
P-121461
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ł...
P-121462
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:
C/C++
#include <memory> //dla smart pointerow
#include <vector> //vectory

std::vector < std::unique_ptr < Ksztalt > > v_Ksztalt;

powinno pomóc.
P-121463
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.

C/C++
#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();
    }
}
P-121469
maly
» 2014-11-26 20:11:25
jest tylko jeden błąd
Nie ma to jak konkretna informacja.

C/C++
class Ksztalt
{
    virtual void Wyswietl() = 0;
};
P-121473
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.
P-121474
« 1 »
  Strona 1 z 1