Itzik.B
Itzik.B

Reputation: 1076

printing two dimensional array after overloading the operator <<

I am trying to overload the operator << and redirect it to another function. I am trying to print a two dimensional array but its seem that the trigger does't working.

friend ostream& operator<<(ostream &out, const Board &c)
    {
        for (int i = 0; i < c.n; i++) {
            for (int j = 0; j < c.n; j++) {
                std::cout << c.board[i][j] << 1; // trying to debug this is not part of the code.
                out << c.board[i][j]; 
            }
            out << endl;
        }
        return out;
    }

This is how i've called it. cout << board << endl; /* Shows an empty board

Source.cpp

#include "Board.h"

#include <iostream>
using namespace std;

int main() {
    Board board{ 3 };  // Initializes a 3x3 board
    cout << board << endl;   /* Shows an empty board:
    ....
    ....
    ....
    ....
    */

    return 0;
}

Board.h

    #pragma once
#include <iostream>
using namespace std;

class Board {
    private:
        int n; // size
        char** board; // matrix
    public:
        Board(int n = 3); // constructor
        Board(const Board& another); // copy contructor
        Board(Board&& another); // move constructor
        ~Board();
        const Board& operator=(const Board& another) {
            if (this != &another) {
                n = another.n;
                for (int i = 0; i < n; i++) {
                    for (int j = 0; j < n; j++) {
                        board[i][j] = another.board[i][j]; // take values from original board into the new board
                    }
                }
            }
            return *this;
        }
        friend ostream& operator<<(ostream &out, const Board &c)
        {
            for (int i = 0; i < c.n; i++) {
                for (int j = 0; j < c.n; j++) {
                    std::cout << c.board[i][j] << 1; // trying to decug this is not part of the code.
                    out << c.board[i][j]; 
                }
                out << endl;
            }
            return out;
        }
};

Board.cpp

#include "Board.h"
#include <iostream>

Board::Board(int n) {
    n = (n >= 3) ? n : 3;

    char** board = new char*[n];
    for (int i = 0; i < n; i++){
        board[i] = new char[n];
    }

    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            board[i][j] = '.';
}
Board::Board(const Board& another) { // copy contructor
    n = another.n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            board[i][j] = another.board[i][j]; // take values from original board into the copy board
        }
    }
}
Board::Board(Board&& another) { // move constructor
    n = another.n;
    board = another.board; // copy by reference
}
Board::~Board(){
    for (int i = 0; i < n; i++) {
        delete[] board[i];
    }
    delete[] board;
}

BTW: I tried to upload the code on pastebin links but the editor doesn't let me.

Thanks I am hoping I was clear enough.

Upvotes: 0

Views: 326

Answers (1)

NathanOliver
NathanOliver

Reputation: 180710

You have a few issues. First, in your constructor you have

char** board = new char*[n];

This declaration hides the class member board that you have. That means when the constructor exits the board class member is left uninitialized. What you need is just

board = new char*[n];

to fix that.

Your second issue is the same thing for n in your constructor. You have a parameter for the constructor named n which hides the n member of the class. Either access the n of the class like

this->n = (n >= 3) ? n : 3;

or just change Board::Board(int n) to something like Board::Board(int n_) and then you would use

n = (n_ >= 3) ? n_ : 3;

Your third problem is with your copy constructor. It doesn't allocate any memory so all the writing you do to board is undefined behavior. You need to change to

Board::Board(const Board& another) { // copy contructor
    n = another.n;
    board = new char*[n];
    for (int i = 0; i < n; i++){
        board[i] = new char[n];
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            board[i][j] = another.board[i][j]; // take values from original board into the copy board
        }
    }
}

for it to work correctly.

Lastly, your move constructor does not set the moved to object into a delete-able state. You need

Board::Board(Board&& another) { // move constructor
    n = another.n;
    board = another.board; // copy by reference
    another.board = nullptr; // null out moved from object
}

to do that.

Upvotes: 2

Related Questions