C ++ beginner question regarding symbols

I was just messing around with some C ++ for now trying to make a simple tic-tac-toe game and I ran into some problem. This is my code:

#include <iostream>
using namespace std;

class Square {
public:
    char getState() const;
    void setState(char);
    Square();
    ~Square();
private:
    char * pState;
};

class Board {
public:
    Board();
    ~Board();
    void printBoard() const;
    Square getSquare(short x, short y) const;
private:
    Square board[3][3];
};

int main() {
    Board board;
    board.getSquare(1,2).setState('1');
    board.printBoard();
    return 0;
}

Square::Square() {
    pState = new char;
    *pState = ' ';
}
Square::~Square() {
    delete pState;
}
char Square::getState() const {
    return *pState;
}
void Square::setState(char set) {
    *pState = set;
}

Board::~Board() {

}
Board::Board() {

}
void Board::printBoard() const {
    for (int x = 0; x < 3; x++) {
        cout << "|";
        for (int y = 0; y < 3; y++) {
            cout << board[x][y].getState();
        }
        cout << "|" << endl;
    }
}
Square Board::getSquare(short x, short y) const {
    return board[x][y];
}

      

Forgive me if there are frankly obvious problems with it or if it is stupidly written, this is my first C ++ program: p However, the problem is that when I try to set the square of 1.2 to char '1', it does not print as 1 , it prints like some weird character that I didn't recognize.

Can anyone tell me why? :)

Thanks in advance.

+2


a source to share


4 answers


  • You don't need to use new

    to instantiate variables.

  • Try changing your state variable to char

    instead of char *

    (pointer to char

    ).

  • In general, a type is char *

    used to indicate a collection (array) of nul-terminated characters.

  • It is also set

    a data type in a namespace std

    . Just change the name to something else, eg new_value

    .

  • The method getState()

    returns a copy of the state, not a reference to the state. This is where Java and C ++ differ. Try to return State&

    which is C ++ language to reference the State instance.

  • Your program is a little overloaded for Tic-Tac-Toe; the ancients used arrays char

    instead of this new style called OO.



+4


a source


The method Board::getSquare

returns a copy of the object Square

. The pState

copied object variable Square

points to the same symbol as the original object Square

. When the copied object is Square

destroyed, it deletes the object char

pointed to by the variable pState

. This will override the object char

in the object Square

in Board

. When you go to print, you are printing an invalid object char

.



As others have pointed out, the variable pState

should probably be char

, not char*

. This will take you a step further in solving your problems. You still need to deal with returning an object reference Square

rather than a copy of the object Square

.

+5


a source


Square Board::getSquare(short x, short y) const {
    return board[x][y];
}

      

This is where you keep an instance of a copy of the Square instance. Since there is no constructor , the instance will be copied by memory value. So now there are 2 squares that the state points to the same value.

But the square has a destructor . In the destructor, the state pointer is removed. But then the remaining copy now has a dangling pointer.

  • A square instance of A.
  • The Char pointer pA is allocated and set ' '

    to as A.

    +-----+
    | pA -----> ' '
    +-----+
    
          

  • The temporary square of instance B is bit-copied from A to getSquare

    . This means that the char pointer pB points to the same location pA

    +-----+        
    | pA -----> ' '
    +-----+      ^
    +-----+      |
    | pB --------'
    +-----+
    
          

  • The square instance of B is set '1'

    toState, so the content of pB changes to'1'

    +-----+        
    | pA -----> '1'
    +-----+      ^
    +-----+      |
    | pB --------'
    +-----+  *pB='1'
    
          

  • Instance B's temporary square is destroyed because, well, it's temporary.

    +-----+        
    | pA -----> garbage
    +-----+      ^
    + - - +      |
    : pB --------'
    + - - +  delete pB
    
          

  • Now pA points to garbage.

    +-----+        
    | pA -----> garbage
    +-----+
    
          


You have to return reference to avoid copying,

Square& Board::getSquare(short x, short y) { return board[x][y]; }
//----^ "&" means reference. Similar to pointer, but not rebindable/nullable. 
//      Just think of it as a read-only pointer without needing a "*"

const Square& Board::getSquare(short x, short y) const { return board[x][y]; }
// Both mutable and const versions are needed. (Yes, code duplication.)

      

and / or provide a copy constructor.

class Square {
public:
  ...
  Square(const Square&);

...
Square::Square(const Square& other) {
  pState = new char;
  *pState = *other.pState;
}

      


You can just use

class Square {
public:
    char getState() const;  // { return state; }
    void setState(char);    // { state = input; }
private:
    char state;
};

      

to avoid heap memory mess. cout <<

supports printing char

.

And please don't write C ++ in Java.

+3


a source


Two problems:

1) The method getSquare

is equal const

and therefore returns an object const

.

1) Method getSquare

const

and therefore cannot return a reference const

for a const object.

2) The object returned from getSquare

is a copy of the square on the board.

To fix it:

1) Remove const

from the method getSquare

.

2) change getSquare

to get the link back:Square & Board::getSquare(short x, short y)

+2


a source







All Articles