Bukaj25 Bukaj25 - 1 month ago 6
C++ Question

how to get to field of 2D object dynamic array?

I would like to create Conway's Game of Life. I have two classes Cell and Board and in Board I want create 2D dynamic array type Cell. I don't have any idea how to get in this array to Cell's fields. Compiler show


C:\Users\Ja\Desktop\ObjectProject\ObjectGameOfLife\board.cpp:54: error: C2248: 'Cell::state_current': cannot access private member declared in class 'Cell'


Sorry for my english.

#ifndef CELL_H
#define CELL_H

#include <iostream>
#include <cstdlib>

using namespace std;

class Cell
{
bool state_current;
bool state_future;
int neighbors;

void editCell(bool n_state);

public:
Cell();
void show();
void edit();
};


cell.cpp

#endif // CELL_H
#include "cell.h"

Cell::Cell()
{
int a=0;

a=rand()%2;
if(a==1)
state_current=true;
else
state_current=false;

state_future=false;
neighbors=0;
}

void Cell::show()
{
if(state_current==true)
cout<<'X';
else
cout<<'O';
}

void Cell::editCell(bool n_state)
{
state_current=n_state;
}

void Cell::edit()
{
int option;

cout<<"choose avaible option:\n0.dead\n1.alive"<<endl;

cin>>option;
while(option!=1 && option!=0)
{
cout<<"choose avaible option"<<endl;
cin>>option;
}

if(option==1)
editCell(true);
else
editCell(false);
}


board.h

#ifndef BOARD_H
#define BOARD_H

#include "cell.h"

class Board
{
int v;
int c;
Cell **t;
public:
Board(int a=10, int b=10); //konstruktor z wartościami domyślnymi
void showBoard();
void getSize();
void createBoard();
void checkNeighborhood(int x, int y);
void rules(int x, int y);
void nextGen();
};

#endif // BOARD_H


board.cpp

#include "board.h"

Board::Board(int a,int b)
{
v=a;
c=b;
t=new Cell *[v];

for(int i=0; i<v; i++)
t[i]=new Cell [c];
}

void Board::createBoard()
{
t=new Cell *[v];

for(int i=0; i<v; i++)
t[i]=new Cell [c];
}

void Board::showBoard()
{
for(int i=0; i<v; i++)
{
for(int j=0; j<c; j++)
t[i][j].show();
cout<<endl;
}
}

void Board::getSize()
{
int a,b;

cout<<"Enter natural numbers"<<endl;
cin>>a;
cin>>b;
while(a<1 && b<1)
{
cout<<"Board can't have this size. Enter natural numbers"<<endl;
cin>>a;
cin>>b;
}
v=a;
c=b;
}

void Board::checkNeighborhood(int x, int y)
{
for(int i=x-1; i<x+2; i++)
for(int j=y-1; j<y+2; j++)
if(i>=0 && i<v && j>=0 && j<c)
if(!(i==x && j==y))
if(t[i][j].state_current==true)//first crash
t[i][j].neighbors++;
}

void Board::rules(int x, int y)
{

if(t[x][y].state_current==true)
if(t[x][y].neighbors<2 || t[x][y].neighbors)
t[x][y].state_future=false;
else
t[x][y].state_future=true;
else
if(t[x][y].neighbors==3)
t[x][y].state_future=true;
else
t[x][y].state_future=false;
}

void Board::nextGen()
{
for(int i=0; i<v; i++)
for(int j=0; j<c; j++)
{
rules(i,j);
t[i][j].state_current=t[i][j].state_future;
}
}

Answer

The problem is exactly what it says that it is; you are attempting to modify a private attribute from another object. In this line:

     if(t[i][j].state_current==true)//first crash

Notice that you reach right into the object and try to grab hold of the attribute (member variable) rather than asking the Cell what it's state is.

Part of the purpose of encapsulating functionality and making them private is to prevent other objects from reaching inside and modifying things willy-nilly. Even though you are simply performing a check here, the proper way to do it is to use an object method to interrogate the object. Add something like this to your Cell.h and Cell.cpp as a Public function:

boolean Cell::status()
{
  return state_current;
}

Then call it like so:

if(t[i][j].status()==true)

Obviously, you should take the same object-oriented approach to the rest of the manipulation that you then do to the cells. Don't try to modify the cell directly, tell the object how it should be modified and then let the cell manage it. This makes your code reusable and far more readable.