I am trying to do the following:
class Test{
private:
int x;
int y;
// Create array[][] here
public:
Test(const int x, const int y){
this->x = x;
this->y = y;
// set: array[x][y] here
}
};
As you see I would like to create a 2d-Array, while the bounds will be given in the constructor.
How can I achieve this?
It works with an usual array:
class Test{
private:
int x;
int y;
int *array;
public:
Test(const int x, const int y){
this->array = new int[x]; // works
// this->array = new int[x][y] does not work
this->x = x;
this->y = y;
}
};
You may be bumping into the problem of "All dimensions must be constants except the leftmost" discussed here.
Instead, try the following:
class Test {
private:
int x;
int y;
int** myArray;
public:
Test(const int x, const int y) : x(x), y(y) {
myArray = new int*[x];
for (int firstDimension = 0; firstDimension < x; firstDimension++) {
myArray[firstDimension] = new int[y];
for (int secondDimension = 0; secondDimension < y; secondDimension++) {
myArray[firstDimension][secondDimension] = secondDimension;
}
}
}
~Test() {
for(int i = 0; i < x; i++)
delete[] myArray[i];
delete[] myArray;
}
};
you should consider allocating memory with pointers, should be as follows:
class Test{
private:
int x;
int y;
int **array;
public:
Test(const int x, const int y){
int i;
this->array = new int*[x]; // first level pointer asignation
for(i=0;i<x;i++){
this->array[x] = new int[y]; // second level pointer asignation
}
// this->array = new int[x][y] does not work
this->x = x;
this->y = y;
}
};
see this.
Related
#include <iostream>
using namespace std;
class Point {
int x, y;
public:
Point ():x(0),y(0){};
void setX (int xx){x = xx;};
void setY (int yy){y = yy;};
int getX (){return x;};
int getY (){return y;};
};
class Polygon {
int n;
double degree;
Point* vertex;
public:
Polygon (int nn):n(nn){
degree = 360.0 / n;
//vertex = new Point [n];
};
private:
vertex = new Point [n];
};
so I'm trying to declare vertex array using new, but I keep getting this error: data member initializer is not allowed
is 'new' considered initializing?! and I tried doing it in constructor but I think it'll only work in constructor's scope.
I'm also confused about this: n should be initialized before using new, so will this be solved if I just write the declaration after constructor?
class Point {
public:
Point ():x(0),y(0){};
void setX (int xx){x = xx;}
void setY (int yy){y = yy;}
int getX (){return x;}
int getY (){return y;}
//change access level to 'private'.
private:
int x;
int y;
};
class Polygon {
public:
Polygon (int nn):n(nn){
degree = 360.0 / n;
vertex = new Point [n];
}
// deallocate memory from heap
~Polygon () {
delete [] vertex;
}
// overload copy constructor to avoid double free
Polygon (const Polygon& pg) : n(pg.n), degree(pg.degree) {
vertex = new Point [n];
for (int i = 0; i < n; i++) {
vertex[i] = pg.vertex[i];
}
}
// overload assignment operator to avoid memory leak
Polygon& operator=(const Polygon& pg) {
if (this != &pg) {
n = pg.n;
degree = pg.degree;
delete [] vertex;
vertex = new Point[n];
for (int i = 0; i < n; i++) {
vertex[i] = pg.vertex[i];
}
}
return *this;
}
// use pointer to change/get the value.
Point* get_vertex() {
return vertex;
}
//change access level to 'private'.
private:
int n;
double degree;
Point* vertex;
};
I have a public class in which I create an array, this array takes its size from the constructor and needs to be used in other functions (including int main). Therefore the variable must be public. my code looks something along these lines:
class myclass {
public:
int parameter1;
int parameter2;
myclass(int p, int p2) {
parameter1 = p;
parameter2 = p2;
}
void makeArray() {
int array[parameter1][parameter2]; //I want this array to be public as the next method needs access to it
}
void otherFunction() {
array[1][2] = 5; //just an example of what i need to do
}
}
Look up how to use pointers and dynamic memory..
To do what you want would be something like:
class myclass {
public:
int parameter1;
int parameter2;
int **a;
myclass(int p, int p2) {
parameter1 = p;
parameter2 = p2;
a = nullptr;
}
~myclass() {
// TODO: delete "a"
}
void makeArray() {
// TODO: delete "a" if it has already been allocated
a = new *int[parameter1];
for (int i = 0; i < parameter1; ++i) {
a[i] = new int[parameter2];
}
}
void otherFunction() {
// TODO: check that "a" has already been allocated
a[1][2] = 5; //just an example of what i need to do
}
}
You could also allocate the array in the constructor since you have the necessary information being passed in already.
This is more optimized way to do the same thing:
class myclass {
public:
int parameter1;
int parameter2;
int *array;
myclass(int p1, int p2) {
parameter1 = p1;
parameter2 = p2;
}
void makeArray() {
array = new int[parameter1*parameter2];
}
void otherFunction() {
// ary[i][j] is then rewritten as ary[i*sizeY+j]
array[1*parameter2+2] = 5;
}
};
int main()
{
int sizeX = 5;
int sizeY = 5;
myclass m1(sizeX,sizeY);
m1.makeArray();
m1.otherFunction();
cout << m1.array[1*sizeY+2] << endl;
return 0;
}
I have the following class which is called CoordinatesList. It contains a dynamic array of Coordinates, where each coordinate has 3 integers; x,y, and z.
In the class CoordinatesList, I have two different member operator=, I am slightly confused about what is the difference between them?
Will it work the same if I inherited the class coordinates in the class CoordinatesList
class Coordinates {//this is a complete class, do not modify it.
public:
Coordinates() {
x = new int; y = new int; z = new int;
*x = *z = *y = 0;
}
Coordinates(int _x, int _y, int _z) {
x = new int; y = new int; z = new int;
*x = _x;
*z = _y;
*y = _z;
}
Coordinates(const Coordinates& rhs) { // copy constructor
x = new int; y = new int; z = new int;
*x = *(rhs.x);
*y = *(rhs.y);
*z = *(rhs.z);
}
~Coordinates() {
delete x; delete y; delete z;
}
void operator=(const Coordinates& rhs) {//simplified operator=
*x = *(rhs.x);
*y = *(rhs.y);
*z = *(rhs.z);
}
int getx() const { return *x; }
int gety() const { return *y; }
int getz() const { return *z; }
void setx(int _x) { *x = _x; }
void sety(int _y) { *y = _y; }
void setz(int _z) { *z = _z; }
friend ostream& operator<< (ostream& out, const Coordinates& rhs) {
out << "[" << *(rhs.x) << "," << *(rhs.y) << "," << *(rhs.z) << "]" << endl;
return out;
}
private:
int *x, *y, *z;
}; //--------------------------------------------------------------
class CoordinatesList {
public:
/*CoordinatesList & operator=(const CoordinatesList &rhs)
{
if (size != rhs.size)
{
delete[] list;
size = rhs.size;
list = new Coordinates[size];
}
for (int i = 0; i < size; i++)
{
list[i].Coordinates::operator=(rhs.list[i]);
}
return *this;
} */
CoordinatesList operator=(const CoordinatesList & rhs)
{
//check if sizes are differernt
if (size != rhs.size)
{
delete[] list; //this calls ~coordinates
size = rhs.size;
list = new Coordinates[size];
}
//copy content
for (int i = 0; i < size; i++) {
//list[i] = rhs.list[i];
//will work as operator= is defined for Coordinates
list[i].setx(rhs.list[i].getx());
list[i].sety(rhs.list[i].gety());
list[i].setz(rhs.list[i].getz());
}
return *this;
}
private:
Coordinates * list;
int size;
};
using CL = CoordinatesList; to save on typing.
The difference is that one returns a reference, one returns a copy.
The idiomatic way is to return a reference to *this, so use this one:
CL& operator=(const CL& rhs){/*...*/ return *this;}
Note that having both versions defined will result in a compiler error because functions cannot differ only by their return values.
Usage of operator=:
CL a = CL(<args>);// (1)
CL b,c;
b = a; // (2)
b.operator=(a); //(3)
c = b = a; // (4)
c.operator=(b.operator=(a)); // (5)
(1) Does not call any CL::operator= but a constructor CL::CL(<args>). An object is being created, so a constructor must be called no matter the equal sign.
(2) Is only syntactic sugar for (3). Calls CL::operator= and discards any returned value.
(4) Again, its only syntactic sugar for (5). First the right operator= is evaluated and the returned value is passed to the left operator= as its argument. In this case having operator= returning a copy will indeed make a copy. That's the reason why the second option is preferred as it does not incur this additional and unneeded cost. Also this should be a good explanation for why the function returns anything at all, if it returned void then this syntax would not be possible.
I'm trying to construct a two-dimensional boolean array with a class I've created called Grid. The Grid object is a private member class of another class called GameOfLife. Whenever I create a GameOfLife object with the parameters belove, the Grid object first gets created with the default constructor, then it gets created again with the constructor with parameters, and then for some reason Grid's deconstructor runs and deletes everything ? I'm really out of ideas :p I'm running MinGW GCC on Eclipse Luna.
Main.cpp
const int HEIGHT = 25;
const int WIDTH = 25;
#include <iostream>
#include "GameOfLife.h"
int main(int argc, const char * argv[]) {
GameOfLife game = GameOfLife(HEIGHT, WIDTH, false);
game.play();
return 0;
}
Grid.h
#ifndef __Game_Of_Life__Grid__
#define __Game_Of_Life__Grid__
#include <stdio.h>
class Grid {
public:
Grid(int y, int x, bool state);
Grid();
void allocate(int x, int y, bool state);
void deallocate();
void set(int x, int y, bool state);
bool get(int x, int y);
void setAll(bool state);
void switchBoards();
~Grid();
private:
bool ** oldGeneration;
bool ** newGeneration;
int height;
int width;
};
#endif /* defined(__Game_Of_Life__Grid__) */
Grid.cpp
#include "Grid.h"
Grid::Grid(int y, int x, bool state) {
allocate(x, y, state);
}
void Grid::allocate(int x, int y, bool state) {
height = y;
width = x;
oldGeneration = new bool*[height];
newGeneration = new bool*[height];
for (int i = 0; i < height; i++) {
oldGeneration[i] = new bool[width];
newGeneration[i] = new bool[width];
}
}
Grid::~Grid() {
deallocate();
}
void Grid::switchBoards() {
bool ** temp = oldGeneration;
oldGeneration = newGeneration;
newGeneration = temp;
delete temp;
}
bool Grid::get(int x, int y) {
return oldGeneration[y][x];
}
void Grid::set(int x, int y, bool state) {
newGeneration[y][x] = state;
}
void Grid::deallocate() {
if (oldGeneration != NULL || newGeneration != NULL) {
for (int i = 0; i < height; i++) {
delete [] oldGeneration[i];
delete [] newGeneration[i];
}
delete [] oldGeneration;
delete [] newGeneration;
}
return;
}
Grid::Grid() {
oldGeneration = NULL;
newGeneration = NULL;
width = 0;
height = 0;
}
void Grid::setAll(bool state) {
for (int i = 0; i < height; i++) {
for (int n = 0; n < width; n++) {
newGeneration[i][n] = state;
}
}
}
GameOfLife.h
#ifndef __Game_Of_Life__GameOfLife__
#define __Game_Of_Life__GameOfLife__
#include <stdio.h>
#include "Grid.h"
#include <iostream>
class GameOfLife {
private:
Grid board;
public:
GameOfLife(int y, int x, bool state);
GameOfLife();
~GameOfLife();
void play();
void welcome();
void makeBoard();
void updateBoard();
int findAliveNeighbours(int x, int y);
};
#endif /* defined(__Conway__GameOfLife__) */
GameOfLife.cpp
#include "GameOfLife.h"
const int WIDTH = 100;
const int HEIGHT= 75;
GameOfLife::GameOfLife(int y, int x, bool state) {
board = Grid(y, x, state);
}
GameOfLife::GameOfLife() {
board = Grid();
}
GameOfLife::~GameOfLife() {
board.deallocate();
}
void GameOfLife::play() {
welcome();
makeBoard();
for (int i = 0; i < HEIGHT; i++) {
for (int n = 0; n < WIDTH; n++) {
std::cout << board.get(n,i) << " ";
}
std::cout << std::endl;
}
updateBoard();
std::cout << std::endl;
for (int i = 0; i < HEIGHT; i++) {
for (int n = 0; n < WIDTH; n++) {
std::cout << board.get(n,i) << " ";
}
std::cout << std::endl;
}
}
void GameOfLife::makeBoard() {
int x1,x2,x3,x4, y1,y2,y3,y4;
x1 = 10; y1 = 10;
x2 = 10; y2 = 11;
x3 = 10; y3 = 12;
x4 = 11; y4 = 13;
int x5 = 0; int y5 = 0;
board.set(x1, y1, true);
board.set(x2, y2, true);
board.set(x3, y3, true);
board.set(x4, y4, true);
board.set(x5, y5, true);
}
void GameOfLife::welcome() {
std::cout << "Welcome to Conway's Game Of Life"
<< std::endl;
}
GameOfLife::GameOfLife(int y, int x, bool state) {
// board is a member variable that gets initialized
// with the default constructor.
// Then it gets replaced by assignment with a different
// Grid object. The temporary object gets deleted at
// the end of the line.
board = Grid(y, x, state);
}
Change the implementation to:
GameOfLife::GameOfLife(int y, int x, bool state) : board(y, x, state) {}
Similarly, change the default constructor to:
GameOfLife::GameOfLife() {}
The more important problem that needs to be fixed is that you are breaking The Rule of Three.
You need to add proper implementations of the copy constructor and the copy assignment opertor in Grid.
The other, and better, option is to change the internal data of Grid to
std::vector<std::vector<bool>> oldGeneration;
std::vector<std::vector<bool>> newGeneration;
Then, the compiler generated copy constructor and copy assignment operator will be good enough.
I would like to know, how to loop through a array of int to get its value and set its value. I know how to use the for loop to to get instantly, but I am not sure how it works, when I am using in user created objects and esp using the get set method.
I am totally new to this and have very little guidance from my lectures. I hope you guys can assist to help me. This up to where I have done.
//point.h
class point {
private:
int x[4];
public:
int getx();
void setx();
};
//point.cpp
class point {
point::getx(){
// ??????
}
point::setx(){
// ???????
}
//main.cpp
int main(){
point objPoint;
objPoint.setx(/* ???? */);
???? = objPoint.getx();
}
First of all, your getx method should return int*, not just int, and your setx should receive const int* as parameter. Second, in your point.cpp file you shouldn't redeclare class point.
int* point::getx() { //version with copying
int* ans = new int[4];
for (int i = 0; i < 4; i++) {
ans[i] = x[i];
}
return ans;
}
void point::setx(const int* y) {
for (int i = 0; i < 4; i++) {
x[i] = y[i];
}
}
Then you can use them like this
int y[4] = {1, 2, 3, 4};
int* z;
objPoint.setx(y);
z = objPoint.getx();
Just don't forget to delete[] z when you're done.
If I'm understanding you correctly, you probably want something like more this:
point.h:
class Point{
private:
int x, y;
public:
int getx();
int gety();
void setx(int value);
void sety(int value);
};
point.cpp
int Point::getx() { return x; }
int Point::gety() { return y; }
void Point::setx(int value) { x = value; }
void Point::sety(int value) { x = value; }
main.cpp
int main(int argc, char *argv[])
{
Point objPoint;
objPoint.setx(1);
int x = objPoint.getx();
cout << "x=" << x << endl;
return 0
}
Even better, you might wish to define a constructor like Point (int xvalue, int yvalue).
IMHO ...