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

Problem z metodami wirtualnymi

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
321 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,020 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 (156,320 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 (155,140 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 (155,140 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ź 319 wizyt
pytanie zadane 12 czerwca 2018 w Java przez Patrycja Ły Początkujący (270 p.)
0 głosów
0 odpowiedzi 111 wizyt
pytanie zadane 24 sierpnia 2016 w Systemy operacyjne, programy przez privlaka Nowicjusz (140 p.)
0 głosów
1 odpowiedź 191 wizyt
pytanie zadane 19 czerwca 2017 w C i C++ przez Rivit Nowicjusz (200 p.)

93,158 zapytań

142,171 odpowiedzi

321,881 komentarzy

62,487 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 224p. - nidomika
  2. 224p. - Marcin Putra
  3. 223p. - dia-Chann
  4. 221p. - ssynowiec
  5. 217p. - Mikbac
  6. 216p. - CC PL
  7. 215p. - Łukasz Piwowar
  8. 212p. - zmmz89
  9. 210p. - Adrian Wieprzkowicz
  10. 208p. - rafalszastok
  11. 206p. - Michal Drewniak
  12. 204p. - Łukasz Eckert
  13. 202p. - rucin93
  14. 200p. - robwarsz
  15. 198p. - TheLukaszNs
Szczegóły i pełne wyniki

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...