• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem z metodami wirtualnymi

Object Storage Arubacloud
0 głosów
199 wizyt
pytanie zadane 11 stycznia 2021 w C i C++ przez szymonkozy Nowicjusz (140 p.)

Hej mam problem, wyskakuje mi błąd:

 pure virtual method called terminate called without an active exception

W moich klasach nie mam żadnego konstruktora ani destruktora, a z tego co czytałem na forach to był najczestszy błąd z tym związany.

class Figura{
public:

virtual void ruch(int,int)=0;
virtual void bicie(int,int)=0;

virtual void zapis_x(int)=0;
virtual void zapis_y(int)=0;
virtual void zapis_licznik()=0;
virtual int odczyt_kolor()=0;
virtual int odczyt_x()=0;
virtual int odczyt_y()=0;
virtual string odczyt_wyglad()=0;
virtual int odczyt_licznik()=0;
virtual int odczyt_wartosc()=0;
virtual void drukuj_wyglad()=0;
virtual void drukuj_x()=0;
virtual void drukuj_y()=0;

int kolor;
int wartosc;
int x;
int y;
//Figura* wsk;
string wyglad;
static int licznik;
};

class pionek
:public Figura
{
void ruch(int,int);
void bicie(int,int);
void zapis_x(int);
void zapis_y(int);
void zapis_licznik();
int odczyt_x();
int odczyt_y();
int odczyt_kolor();
string odczyt_wyglad();
int odczyt_licznik();
int odczyt_wartosc();
void drukuj_wyglad();
void drukuj_x();
void drukuj_y();
public:
int kolor;
int wartosc;
int x;
int y;
}
class pole{

public:
int kolor; //bialy to 0, czarny to 1
int linia_x;
int kolumna_y;
bool zajete;
string wyglad;
Figura* figura;
};

 

To są moje klasy


void wybor()
{
int x,y,gdzie_x,gdzie_y;
cin >> x >>y>>gdzie_x>>gdzie_y;

szachownica[x][y].figura->ruch(gdzie_x,gdzie_y);
}

A w tej funkcji wywala mi program podczas wywoływania metody ruch.

pole szachownica[8][8]

Cała tabela jest zainicjalizowana, a wszystkie wskaźniki na klasę Figura dobrze ustawione, nie wiem w czym jest problem. POMOCY 

komentarz 11 stycznia 2021 przez tkz Nałogowiec (42,000 p.)
Podaj cały kod, bo ten jest niekompletny. W którym miejscu tworzysz obiekt przez new?
komentarz 11 stycznia 2021 przez szymonkozy Nowicjusz (140 p.)
Wszystkie obiekty deklaruję "ręcznie" i potem przypisuję je do każdego pola. np

szachownica[0][0].figura = &obiekt

2 odpowiedzi

0 głosów
odpowiedź 11 stycznia 2021 przez mokrowski Mędrzec (155,460 p.)
Zacznijmy od tego że masz trochę "namieszane koncepcyjnie".

Warto odpowiedzieć sobie na kilka pytań:

1. Czy bierka powinna wiedzieć na jakim polu stoi?

 - jeśli tak, to po co ma wiedzieć pole w jakim jest miejscu ?

 - jeśli nie, to pole będąc w danym miejscu (współrzędne szachownicy), powinno wiedzieć że trzyma daną bierkę.

2. Jakie atrybuty ma pole?

 - zdroworozsądkowo, albo ma bierkę albo nie, ma zawsze kolor czarny lub biały

3. Dlaczego każda z klas, nie posiada konstruktora który poprawnie będzie ją inicjował?

Jeśli nie będziesz tego miał, skazujesz się na bardzo rozbudowaną if'ologię i generowanie niepotrzebnych błędów.

4. Która z klas będzie odpowiedzialna za niszczenie obiektów bierek? (bo nie ma sensu robić tego w main jako jawne pętle)

5. Czy adresowanie pola przez dwa indeksy, ma sens jeśli są to szachy? Z mojej wiedzy wynika że w notacji dla szachów podaje się nazwę kolumny (a - h) i numer wiersza (1 - 8) (na początek zacznij od takiej notacji.. później dojdziesz do docelowej).

6. Kto (jaka klasa) w Twojej aplikacji będzie odpowiedzialna za sprawdzenie ruchu?

 - szachownica - po co jej wiedza na temat "rodzaj bierki -> poprawny ruch"

 - pole - totalnie bez sensu....

 - bierka - to ma sens jak dostanie informację o polu źródła i celu.

7. Brakuje w klasie z metodami wirtualnymi, wirtualnego destruktora.

 

Proponuję odpowiedzieć sobie na te pytania i zacząć budowę aplikacji krok po kroku...
–2 głosów
odpowiedź 11 stycznia 2021 przez tangarr Mędrzec (154,780 p.)

Zacznijmy od tego, że używanie metod wirtualnych wymaga utworzenia destruktora wirtualnego w klasie bazowej.

komentarz 11 stycznia 2021 przez szymonkozy Nowicjusz (140 p.)
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <windows.h>
#include <fstream>
#include "klasy.h"
//#include <>
using namespace std;

/////////////////////////////////////////////////////////////////////////////////////////////

 pole a1,a2,a3,a4,a5,a6,a7,a8,b1,b2,b3,b4,b5,b6,b7,b8,c1,c2,c3,c4,c5,c6,c7,c8,d1,d2,d3,d4,d5,d6,d7,d8,e1,e2,e3,e4,e5,e6,e7,e8,f1,f2,f3,f4,f5,f6,f7,f8,g1,g2,g3,g4,g5,g6,g7,g8,h1,h2,h3,h4,h5,h6,h7,h8;
 pole szachownica[8][8]= {{a1,a2,a3,a4,a5,a6,a7,a8},{b1,b2,b3,b4,b5,b6,b7,b8},{c1,c2,c3,c4,c5,c6,c7,c8},{d1,d2,d3,d4,d5,d6,d7,d8},{e1,e2,e3,e4,e5,e6,e7,e8},{f1,f2,f3,f4,f5,f6,f7,f8},{g1,g2,g3,g4,g5,g6,g7,g8},{h1,h2,h3,h4,h5,h6,h7,h8}};

/////////////////////////////////////////////////////////////////////////////////////////////

char dane[6];

int pionek::licznik;
int goniec::licznik;
int skoczek::licznik;
int wieza::licznik;
int hetman::licznik;
int krol::licznik;
int nic::licznik;

int main()
{
   nowagra(szachownica);
 //  cout<<szachownica[0][0].figura->kolor;

   do{

   wybor();
   system("CLS");
   drukuj(szachownica);
   system("CLS");
   drukuj(szachownica);

   }
   while(1);//kolejny_ruch=='t');

}

main

komentarz 11 stycznia 2021 przez szymonkozy Nowicjusz (140 p.)
#include <iostream>
#include "klasy.h"
#include <iomanip>
#include <fstream>
#include <string>

using namespace std;

//RUCH PIONKA
void pionek::ruch(int gdzie_x,int gdzie_y)
{
    //ruchy pionkiem
    if(kolor==15)
    {
        //RUCH BIALYCH DO PRZODU O 1
        if(((y+1==gdzie_y)&&(gdzie_x==x))&&(szachownica[gdzie_x][gdzie_y].zajete==false))
        {
            szachownica[x][y].zajete=false;
            //////////////////////////////////////////////
            szachownica[gdzie_x][gdzie_y].zajete = true;
            szachownica[gdzie_x][gdzie_y].figura = szachownica[x][y].figura;
            //////////////////////////////////////////////
            if(szachownica[x][y].kolor==0)
                szachownica[x][y].wyglad = 254;
            else
                szachownica[x][y].figura->wyglad=111;
            szachownica[gdzie_x][gdzie_y].figura->zapis_x(gdzie_x);
            szachownica[gdzie_x][gdzie_y].figura->zapis_y(gdzie_y);
            licznik+=1;
            //  zapis_ruchu(dane);
        }
        //RUCH BIALYCH DO PRZODU O 2
        else if(((y+2==gdzie_y)&&(gdzie_x==x)&&(szachownica[x][y].figura->odczyt_y()==1))&&(szachownica[gdzie_x][gdzie_y].zajete==false))
        {

            szachownica[x][y].zajete=false;
            //////////////////////////////////////////////
            szachownica[gdzie_x][gdzie_y].zajete = true;
            szachownica[gdzie_x][gdzie_y].figura = szachownica[x][y].figura;
            //////////////////////////////////////////////
            if(szachownica[x][y].kolor==0)
                szachownica[x][y].wyglad=254;
            else
                szachownica[x][y].wyglad=111;
            szachownica[gdzie_x][gdzie_y].figura->zapis_x(gdzie_x);
            szachownica[gdzie_x][gdzie_y].figura->zapis_y(gdzie_y);
            licznik+=1;
            //zapis_ruchu(dane);
        }
        else
        {
            cout << "Nie mozna wykonac tego ruchu!\n";
            system("pause");
        }
    }

    else if(kolor==8)
    {
        //RUCH CZARNYMI DO PRZODU O 1
        if(((y-1==gdzie_y)&&(gdzie_x==x))&&(szachownica[gdzie_x][gdzie_y].zajete==false))
        {
            szachownica[x][y].zajete=false;
            //////////////////////////////////////////////
            szachownica[gdzie_x][gdzie_y].zajete = true;
            szachownica[gdzie_x][gdzie_y].figura = szachownica[x][y].figura;

            //////////////////////////////////////////////
            if(szachownica[x][y].kolor==0)
                szachownica[x][y].wyglad=254;

            else
                szachownica[x][y].wyglad=111;
            szachownica[gdzie_x][gdzie_y].figura->zapis_x(gdzie_x);
            szachownica[gdzie_x][gdzie_y].figura->zapis_y(gdzie_y);
            licznik+=1;
            //  zapis_ruchu(dane);
        }
        //RUCH CZARNYMI DO PRZODU O 2
        else if(((y-2==gdzie_y)&&(gdzie_x==x)&&(szachownica[x][y].figura->odczyt_y()==6))&&(szachownica[gdzie_x][gdzie_y].zajete==false))
        {
            szachownica[x][y].zajete=false;
            //////////////////////////////////////////////
            szachownica[gdzie_x][gdzie_y].zajete = true;
            szachownica[gdzie_x][gdzie_y].figura = szachownica[x][y].figura;

            //////////////////////////////////////////////
            if(szachownica[x][y].kolor==0)
                szachownica[x][y].wyglad=254;

            else
                szachownica[x][y].wyglad=111;
            szachownica[gdzie_x][gdzie_y].figura->zapis_x(gdzie_x);
            szachownica[gdzie_x][gdzie_y].figura->zapis_y(gdzie_y);
            licznik+=1;
            // zapis_ruchu(dane);
        }
        else
        {
            cout << "Nie mozna wykonac tego ruchu!\n";
            system("pause");
        }
    }

}

/////////////////////////////////////////////////////////////////////////////////////////////

//BICIE PIONKIEM
void pionek::bicie(int gdzie_x,int gdzie_y)
{
    //char t[6];

    if(kolor==15)
    {
        //BICIE BIALYMI
        if(((y+1==gdzie_y)&&(gdzie_x==x+1||gdzie_x==x-1))&&(szachownica[gdzie_x][gdzie_y].zajete)&&(szachownica[gdzie_x][gdzie_y].figura->odczyt_kolor()==8))
        {

            szachownica[x][y].zajete=false;
            //////////////////////////////////////////////
            szachownica[gdzie_x][gdzie_y].zajete = true;
            szachownica[gdzie_x][gdzie_y].figura = szachownica[x][y].figura;
            //////////////////////////////////////////////
            if(szachownica[x][y].kolor==0)
                szachownica[x][y].wyglad=254;
            else
                szachownica[x][y].wyglad=111;
            szachownica[gdzie_x][gdzie_y].figura->zapis_x(gdzie_x);
            szachownica[gdzie_x][gdzie_y].figura->zapis_y(gdzie_y);
            licznik+=1;
            //zapis_ruchu(dane);
        }
        //BICIE BIALYMI W PRZELOCIE

        if((szachownica[x][y].figura->odczyt_y()==4))
        {

        }

    }
    //BICIE CZARNYMI
    else if(((y-1==gdzie_y)&&(gdzie_x==x+1||gdzie_x==x-1))&&(szachownica[gdzie_x][gdzie_y].zajete)&&(szachownica[gdzie_x][gdzie_y].figura->odczyt_kolor()==15))
    {

        szachownica[x][y].zajete=false;

        //////////////////////////////////////////////
        szachownica[gdzie_x][gdzie_y].zajete = true;
        szachownica[gdzie_x][gdzie_y].figura = szachownica[x][y].figura;
        //////////////////////////////////////////////
        if(szachownica[x][y].kolor==0)
            szachownica[x][y].wyglad=254;
        else
            szachownica[x][y].wyglad=111;
        szachownica[gdzie_x][gdzie_y].figura->zapis_x(gdzie_x);
        szachownica[gdzie_x][gdzie_y].figura->zapis_y(gdzie_y);
        licznik+=1;
        //zapis_ruchu(dane);
    }
    else
    {
        cout << "Nie mozna wykonac tego ruchu!\n";
        system("pause");
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////

//RUCH GOÑCA
void goniec::ruch (int gdzie_x, int gdzie_y)
{
    //warunek 1
    bool warunek_1;
    if ((szachownica[gdzie_x][gdzie_y].zajete==false)&&((gdzie_x-x==gdzie_y-y)||(gdzie_x-x==-(gdzie_y-y))))
        warunek_1=true;
    else
    {
        cout << "Nie mozna wykonac tego ruchu!\n";
        system("pause");
    }
    //////////////////////////////////////////////

    //warunek 2
    bool warunek_2=true;

    if ((gdzie_x>x)&&(gdzie_y>y))
    {
        for (int i=1; i<gdzie_x-x; i++)
        {
            if (szachownica[x+i][y+i].zajete==true)
            {
                warunek_2==false;
            }
        }
    }

    if ((gdzie_x>x)&&(gdzie_y<y))
    {
        for (int i=1; i<gdzie_x-x; i++)
        {
            if (szachownica[x+i][y-i].zajete==true)
            {
                warunek_2==false;
            }
        }
    }

    if ((gdzie_x<x)&&(gdzie_y>y))
    {
        for (int i=1; i<x-gdzie_x; i++)
        {
            if (szachownica[x-i][y+i].zajete==true)
            {
                warunek_2==false;
            }
        }
    }

    if ((gdzie_x<x)&&(gdzie_y<y))
    {
        for (int i=1; i<x-gdzie_x; i++)
        {
            if (szachownica[x-i][y-i].zajete==true)
            {
                warunek_2==false;
            }
        }
    }

    //////////////////////////////////////////////
    if ((warunek_1==true)&&(warunek_2==true))
    {
        szachownica[x][y].zajete=false;
        //////////////////////////////////////////////
        szachownica[gdzie_x][gdzie_y].zajete = true;
        szachownica[gdzie_x][gdzie_y].figura = szachownica[x][y].figura;
        //////////////////////////////////////////////
        if(szachownica[x][y].kolor==0)
        {
            szachownica[x][y].wyglad=254;
        }
        else
        {
            szachownica[x][y].wyglad=111;
        }
        szachownica[gdzie_x][gdzie_y].figura->zapis_x(gdzie_x);
        szachownica[gdzie_x][gdzie_y].figura->zapis_y(gdzie_y);
        licznik+=1;
    }
    else
    {
        cout << "Nie mozna wykonac tego ruchu!\n";
        system("pause");
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////

//BICIE GOÑCEM
void goniec::bicie (int gdzie_x, int gdzie_y)
{
    //warunek 1
    bool warunek_1;
    if ((szachownica[gdzie_x][gdzie_y].zajete==true)&&(szachownica[gdzie_x][gdzie_y].figura->odczyt_kolor()!=szachownica[x][y].figura->odczyt_kolor())&&((gdzie_x-x==gdzie_y-y)||(gdzie_x-x==-(gdzie_y-y))))
        warunek_1=true;
    else
    {
        cout << "Nie mozna wykonac tego ruchu!\n";
        system("pause");
    }
    //////////////////////////////////////////////

    //warunek 2
    bool warunek_2=true;

    if ((gdzie_x>x)&&(gdzie_y>y))
    {
        for (int i=1; i<gdzie_x-x; i++)
        {
            if (szachownica[x+i][y+i].zajete==true)
            {
                warunek_2==false;
            }
        }
    }

    if ((gdzie_x>x)&&(gdzie_y<y))
    {
        for (int i=1; i<gdzie_x-x; i++)
        {
            if (szachownica[x+i][y-i].zajete==true)
            {
                warunek_2==false;
            }
        }
    }

    if ((gdzie_x<x)&&(gdzie_y>y))
    {
        for (int i=1; i<x-gdzie_x; i++)
        {
            if (szachownica[x-i][y+i].zajete==true)
            {
                warunek_2==false;
            }
        }
    }

    if ((gdzie_x<x)&&(gdzie_y<y))
    {
        for (int i=1; i<x-gdzie_x; i++)
        {
            if (szachownica[x-i][y-i].zajete==true)
            {
                warunek_2==false;
            }
        }
    }

    if (warunek_1&&warunek_2)
    {
        szachownica[x][y].zajete=false;
        //////////////////////////////////////////////
        szachownica[gdzie_x][gdzie_y].zajete = true;
        szachownica[gdzie_x][gdzie_y].figura = szachownica[x][y].figura;
        //////////////////////////////////////////////
        if(szachownica[x][y].kolor==0)
        {
            szachownica[x][y].wyglad=254;
        }
        else
        {
            szachownica[x][y].wyglad=111;
        }
        szachownica[gdzie_x][gdzie_y].figura->zapis_x(gdzie_x);
        szachownica[gdzie_x][gdzie_y].figura->zapis_y(gdzie_y);
        licznik+=1;
    }
    else
    {
        cout << "Nie mozna wykonac tego ruchu!\n";
        system("pause");
    }
}

funkcje do figur, nie dodałem do wszystkich, ale reszta jest prawie taka sama

komentarz 11 stycznia 2021 przez TOM_CPP Pasjonat (22,640 p.)

funkcje do figur, nie dodałem do wszystkich

I tutaj prawdopodobnie kryje się błąd. Komunikat pure virtual method called oznacza, że któraś z klas dziedziczących po klasie Figura nie posiada implementacji jakieś metody np. ruch.

Jeżeli w klasie bazowej masz pustą/abstrakcyjną metodę wirtualną ( z zerem na końcu = 0 ), to powinna być zaimplementowana w każdej klasie po niej dziedziczącej.

komentarz 11 stycznia 2021 przez tangarr Mędrzec (154,780 p.)

@szymonkozy, 
Ciężko jest mi skomentować funkcję nowagra.
Konstrukcje tam zawarte mogłyby zadziałać w językach posiadających odśmiecacz pamięci.

Dodaj sobie do wszystkich figur konstruktory (w tym konstruktory kopiujące) i destruktory w których będziesz wypisywał co się dzieje.

Zobaczysz, że w wszystkie figury utworzone w funkcji nowagra (oraz ich kopie) są niszczone przy wyjściu z funkcji a tablica szachownica zawiera nieprawidłowe adresy (do pamięci która została zwolniona).

Doczytaj o zmiennych lokalnych funkcji i zasięgu zmiennych. Jak tylko to zrozumiesz zamień alokację figur na stosie na alokację dynamiczną na stercie przy pomocy operatora new i pracuj na otrzymanych w ten sposób wskaźnikach.

Nie zapomnij zwolnić pamięci zaalokowanej przez figurę podczas zdejmowania jej z szacownicy.

komentarz 11 stycznia 2021 przez szymonkozy Nowicjusz (140 p.)
nie dodałem do komentarza, bo chyba się nie mieściło, ale w programie mam te funkcje, więc to nie jest chyba to

Podobne pytania

0 głosów
1 odpowiedź 269 wizyt
pytanie zadane 12 czerwca 2018 w Java przez Patrycja Ły Początkujący (270 p.)
0 głosów
0 odpowiedzi 94 wizyt
pytanie zadane 24 sierpnia 2016 w Systemy operacyjne, programy przez privlaka Nowicjusz (140 p.)
0 głosów
1 odpowiedź 163 wizyt
pytanie zadane 19 czerwca 2017 w C i C++ przez Rivit Nowicjusz (200 p.)

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...