Modyfikowanie tablicy będącej polem klasy za pomocą wskaźnika.

0

Witam,
Przepisałem na nowo swój działający program i niestety, ale wysypuje się.
Zlokalizowałem konkretne miejsce powodujące błąd, ale nie potrafię ogarnąć w czym tkwi problem.

//DWIE ZAINTERESOWANE KLASY
class Board{
    public:
    string name;
    int posx, posy;
    char tab[BOARD_HEIGHT][BOARD_WIDTH];
    Board(string a, int x=2, int y=2);
    void Draw(int posx, int posy);
};

class Bat
{
    public:
    int pos;
    static const int length = 4;
    void Draw(int a);
    Bat(int z);
    void MoveLeft();
    void MoveRight();
};
//METODA POWODUJĄCA BŁĄD 
void Bat::MoveLeft(){
    if(pos>1){
        actBoard->tab[8][8]='X';  //po zakomentowaniu tejże linijki program nie wysypuje się
        pos--;
    }
}
//UŻYCIE METODY MoveLeft() W PROGRAMIE
if (kbhit()){
   char a = getch();
      switch(a)
      {
         case 'a':
            actBat->MoveLeft();
            break;
         case 'd':
            actBat->MoveRight();
            break;
         default:
             break;
      }
}

Analogicznie MoveRight() również powoduje błąd.
Wskaźniki actBat i actBoard są z pewnością ustawione na stworzone obiekty.
BOARD_HEIGHT i BOARD_WIDTH to stałe globalne większe od 8. Na razie mam wszystko w 1 pliku, dla pewności wszystko public.
Kod przepisałem na nowo (zmiana koncepcji), ale w wersji poprzedniej nie było problemów z odpowiednikiem linijki actBoard->tab[8][8]='X';

0

actBoard w takim razie musi wskazywać na coś innego niż obiekt na który ma pokazywać. W tym kodzie nie widzę błędu
chyba że stałe, są mniejsze od 8, ale skoro piszesz, że są wiekszę to powinno być ok

0

Masz tylko trzy możliwości:

  1. actBoard==0
  2. this==0
  3. BOARD_HEIGHTBOARD_WIDTH<88
0
_13th_Dragon napisał(a):

Masz tylko trzy możliwości:

actBoard==0

Board plansza1("Poziom 1",3,3);
Board* actBoard;
actBoard=&plansza1;

this==0

Bat paletka(15);
Bat* actBat;
actBat=&paletka;

BOARD_HEIGHTBOARD_WIDTH<88

</quote> int const BOARD_WIDTH = 30; int const BOARD_HEIGHT = 22;

Zamieszczam cały kod ('protezę'), który podczas kompilacji nie zwraca żadnych błędów, ani ostrzeżeń. Nie ma żadnej funkcjonalności, prócz znalezienia przyczyny problemu przy wciśnięciu klawisza A lub D. Jeszcze na spokojnie wszystko przeanalizuję... Znając życie błąd jest całkowicie gdzieś indziej.

 
#include <iostream>
using namespace std;
#include <cstring>
#include <windows.h>
#include <cstdio>
#include <ctime>
#include <conio.h>


int const DISPLAY_WIDTH = 61;
int const DISPLAY_HEIGHT = 24;
int const BOARD_WIDTH = 30;
int const BOARD_HEIGHT = 22;
int const BAT_HEIGHT = 4;

//---------------------------------------WYSWIETLACZ--------------
class Display{
    public:
    string content;
    Display();
    void Draw();
    void put(int row, int col, string text);
    void clear();
};

Display* actDisp;

Display::Display(){
clear();
}

void Display::clear(){
char background = ' ';
int hm_signs = DISPLAY_HEIGHT * DISPLAY_WIDTH;
content.assign(hm_signs,background);
for(int i=0; i < hm_signs; i++){
if (i<DISPLAY_WIDTH)
    content[i] = '_';

if (i>(hm_signs-DISPLAY_WIDTH))
    content[i] = '_';
}

for(int i=0 ; (i < DISPLAY_HEIGHT); i++){
content[(i+1) * DISPLAY_WIDTH - DISPLAY_WIDTH] ='|';
content[(i+1) * DISPLAY_WIDTH -2] ='|';
content[(i+1) * DISPLAY_WIDTH -1] ='\n';
}
}


void Display::Draw(){
    cout << content << flush;
}

void Display::put(int row, int col, string text){
    content.replace((DISPLAY_WIDTH * row) + col, text.length(), text);
}
//--------------------------------PLANSZA----------------------
class Board
{
    public:
    string name;
    int posx, posy;
    char tab[BOARD_HEIGHT][BOARD_WIDTH];
    Board(string a, int x=2, int y=2);
    void Draw(int posx, int posy);

};

void Board::Draw(int posx,int posy){
    for (int i=0; i<BOARD_HEIGHT;i++){
        for (int j=0; j<BOARD_WIDTH;j++){
        actDisp->content[(posx+i)*DISPLAY_WIDTH+(posy+j)]=tab[i][j];
        }
    }
}

Board::Board(string a, int x, int y): name(a), posx(x), posy(y) {
    for (int i=0;i<=BOARD_HEIGHT-1;i++){
        for(int j=0;j<=BOARD_WIDTH-1;j++){
        tab[i][j]=' ';
        }
    }
    for (int i=0;i<=BOARD_WIDTH-1;i++){
        tab[0][i]='_';
    }
    for (int i=0;i<=BOARD_WIDTH-1;i++){
        tab[BOARD_HEIGHT-1][i]='_';
    }
    for (int i=1;i<=BOARD_HEIGHT-2;i++){
        tab[i][0]='|';
    }
    for (int i=1;i<=BOARD_HEIGHT-2;i++){
        tab[i][BOARD_WIDTH-1]='|';
    }
}

Board* actBoard;
//--------------------------------------PALETKA---------

class Bat
{
    public:
    int pos;
    static const int length = 4;
    void Draw(int a);
    Bat(int z);
    void MoveLeft();
    void MoveRight();
};

void Bat::MoveLeft(){
    if(pos>1){
        actBoard->tab[8][8]='X';
        pos--;
    }
}

void Bat::MoveRight(){
    if(pos<BOARD_WIDTH-length-2){
    actBoard->tab[BOARD_HEIGHT-2][pos]=' ';
    actBoard->tab[BOARD_HEIGHT-2][pos+length+1]=219;
    pos++;
    }

}

Bat::Bat(int z):pos(z){};

void Bat::Draw(int a){
    for(int i=a;i<=(a+length);i++)
    {
        actBoard->tab[BOARD_HEIGHT-2][i]=219;
    }
}

int main()
{
    Display monitor;
    actDisp=&monitor;
    Board plansza1("Poziom 1",3,3);
    Board* actBoard;
    Bat paletka(15);
    Bat* actBat;
    actBat=&paletka;
    actBoard=&plansza1;
    int TimerBall=0, TimerBat=0;
    while (1){
        actDisp->clear();
        system("CLS");
        actBoard->Draw(1,10);
        actDisp->Draw();
        if((TimerBat+30)<=GetTickCount()){
            TimerBat=GetTickCount();
                if (kbhit()){
                    char a = getch();
                    switch(a)
                    {
                    case 'a':
                        actBat->MoveLeft();
                        break;
                    case 'd':
                        actBat->MoveRight();
                        break;
                    default:
                        break;
                    }
                }

        }
    Sleep(20);
    }
    return 0;
}

1

a ja nadal twierdze że masz tam we wskaźniku śmieci ;)

dlaczego? Przysłoniłeś sobie actBoard!
tą w mainie rzeczywiście nadajesz wartość, ale tej globalnej nie. A później korzystasz z tej globalnej

1

No to masz właśnie możliwość nr 1, o której napisałem wcześniej.
W MoveLeft() oraz MoveRight() używasz tej globalnej actBoard, natomiast actBoard=&plansza1
dotyczy tej actBoard wewnątrz main.

0

Dzięki za odp. Problem zrozumiany. Na razie zostawiłem jedynie wskaźnik globalny. Wiele wody w Wiśle by upłynęło, nim zorientowałbym się, że to kwestia przesłonięcia nazwy :)

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