class Itembuilder
{
private:
int numOfX;
int numOfY;
int numOfZ;
int numOfSpc;
int itemMatrix [numOfZ][numOfY][numOfX];
public:
void build (Space spc, Item item)
{
numOfX = item.getX()/spc.getX(); //number of space requirement for X origin
numOfY = item.getY()/spc.getY(); //number of space requirement for Y origin
numOfZ = item.getZ()/spc.getZ(); //number of space requirement for Z origin
for (int layer=1; layer<=numOfZ; layer++) // stating layers of item through Z origin
{
for (int orgY=1; orgY<=numOfY; orgY++) // stating origin Y of a layer
{
for (int orgX=1; orgX<=numOfX; orgX++) // stating origin X
{
itemMatrix[layer][orgY][orgX]=0;
}
}
}
}
};
Hi, I'm very new to coding in C++. I'm trying to build 3D item for allocating in a domain. First, I got "item.get" and "spc.get" variables from other classes. When trying to state the units as 0 with itemMatrix, I got error about non-static condition of private variables. How would I state space units with matrix?
Please correct my codes with proper one
Thanks
The problem is here:
int itemMatrix[numOfZ][numOfY][numOfX];
C++ does not allow you to use values of member variables in declaring other members.
The process of creating a 3D matrix from arrays is a lot simpler if you use nested vectors:
std::vector<std::vector<std::vector<int>>> itemMatrix;
Then you can initialize it in the constructor as follows:
Itembuilder(int numOfX, int numOfY, int numOfZ)
: itemMatrix(numOfX, std::vector<std::vector<int>>(numOfY, std::vector<int>(numOfZ))) {
}
Is there any other way to initialize vector instead of constructor?
The vector needs to be initialized in the constructor in order to make the object consistent upon construction. However, it does not mean that you don't have an option to re-assign the vector once the constructor has finished. If you later need to change the matrix, for example, to change its size, you can re-assign the vector:
void changeSize(int numOfX, int numOfY, int numOfZ) {
itemMatrix = std::vector<std::vector<std::vector<int>>>(
numOfX
, std::vector<std::vector<int>>(numOfY, std::vector<int>(numOfZ))
);
}
Related
I am pretty much new to OOP and C++ but have a project of "graph traversing" (sorry if there's a more formal term).
I am at the very beginning of the project where I have to initialize an 2D grid composed of cases.
I first thought of creating a class Case with 2D-position and a boolean state (occupied of free) as attributes, and a Grid class with a vector of vector of Cases representing the grid.
First I wondered if I'm going in the right direction on terms of Object-oriented programming, and if so I wondered how to initialize the grid in the constructor.
So far I have this for the Case class header :
class case_tab{
int x,y;
bool state;
public:
case_tab(int x_param, int y_param, bool state_param);
};
And the constructor :
case_tab::case_tab(int x_param, int y_param, bool state_param)
:x(x_param),y(y_param),state(state_param)
{}
But the problem comes for the grid constructor (named tableau, here you can see the header):
class tableau
{
int X, Y;
public:
std::vector<std::vector<case_tab>> tab;
tableau(int X_param, int Y_param);
};
Where I don't know how to initialize the grid (tableau) as a grid of free Cases disposed correctly.
I'm pretty sure this is of very basic difficulty but I can't find how to do so, and wonder if it doesn't come from my structure choice in the first place.
Hope someone can help me.
As you declared the attribute tab, it will be initialized by default. So you just have to do two loops so as to fill it. Here is a proposal:
tableau::tableau(int X_param, int Y_param)
: X(X_param), Y(Y_param) {
for(int i = 0; i < X; i++) {
std::vector<case_tab> row;
row.reserve(Y);
for(int j = 0; j < Y; j++) {
row.emplace_back(i, j, false);
}
tab.push_back(row);
}
}
emplace_back generates and adds case_tab objects by calling the constructor that you defined, and reserve allocates memory for the initialized objects.
You should also change tab visibility to private, so as to prevent adding unexpected items to it.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have an assignment and I will list the exercises and then my solution for them as well as the problem that I am nicely asking you to help me understand and resolve it!
The Point class describes a point in a 2D / 3D space and contains
· x - integer attribute
· y - integer attribute
· z - integer attribute
· Attributes are initialized by default
· Class has no default constructor
· The class has two constructors: one that requests X and Y and another that requests all values
· The class has get and set methods for the three values
Each geometric figure is defined by a given number of corners (the lines that join them define the geometric figure)
The AbstractGeometricFigure class contains
· Figure type - string attribute
· is2D - boolean attribute
· number of corners - integer attribute
· Corners array - dynamic vector of Point objects
· area() - a pure virtual method that determines the area of the geometric figure
· perimeter() - pure virtual method that determines the area of the geometric figure
· getCorners() - method that displays the corners of the geometric figure using the template (X, Y) for 2D and (X, Y, Z) for 3D
· addCorner () - method that adds a new corner
I stumble upon the addCorner() method because I need to create another array to which I will add the new corner. In order to create a dynamic array of type Point class, the compiler is telling me to create the default constructor for the class Point. As you can see above, I am not allowed to do it. How can I create another array that will copy the Corners array, and add at the end of it the new value, without implementing the default constructor of class Point? Even if I don't have to create another array, at the exam it might be possible to have such an exercise, and I want to know , what should I do in case I have a dynamic array of type class, and I am not allowed to implement the default constructor of the class.
Here is my code till this point:
#include<iostream>
#include<string>
using namespace std;
class MySpecialException:public exception
{
public:
MySpecialException(string msg) :exception(msg.data())
{
}
};
class Point
{
int x=0;
int y=0;
int z=0;
public:
Point(int X,int Y)
{
this->x = X;
this->y = Y;
}
Point(int X,int Y,int Z)
{
this->x = X;
this->y = Y;
this->z = Z;
}
int getX()
{
return this->x;
}
int getY()
{
return this->y;
}
int getZ()
{
return this->z;
}
void setX(int xcs)
{
this->x = xcs;
}
void setY(int igrec)
{
this->y = igrec;
}
void setZ(int zet)
{
this->z = zet;
}
};
class AbstractGeometricFigure
{
string Figuretype;
bool is2D;
int nbcorners;
Point* Corners;
public:
virtual int area() = 0;
virtual int perimeter() = 0;
void getCorners() {
for (int i = 0; i < nbcorners; ++i) {
cout << "(" << Corners[i].getX() << ", " << Corners[i].getY();
if (is2D) {
cout << ")\n";
}
else {
cout << ", " << Corners[i].getZ() << ")\n";
}
}
}
void addCorner(int newcorner)
{
if (Corners!=NULL)
{
Point* varfuri = new Point[nbcorners];
}
}
};
But if you have the intention to explain to me what happens when I have a dynamic array o type class, class Point,and in that class I must not implement the default constructor. What should I do when I have an exercise like this at the exam?
Update: but I am still waiting for someone to explain to me the answer to my questions.
I was also thinking about implementing it this way:
void addCorner(Point newcorner)
{
if (Corners!=NULL)
{
Corners[nbcorners] = newcorner;
}
}
If you really want varfuri to be an array containing the Point objects directly as elements, with all the semantics it has (e.g. pointer arithmetic etc.), and you are not allowed to use std::vector or similar library containers, then there is currently no completely legal way of doing this in C++.
You can theoretically allocate uninitialized memory blocks with operator new and use single-element placement-new's (via e.g. the various std::uninitialized_* standard library functions) to simulate the behavior of std::vector, but you are then technically not allowed to use a pointer to the first element as if it was a pointer to an array of elements, although in practice this would likely work out fine.
If you don't require array semantics, then you can just implement a linked list or similar non-contiguous container and use that. See comment below for a simpler alternative than a linked list.
Based on your given requirements, these seem to be the only solutions.
As noted by #interjay in a comment below this answer, instead of a linked list you might also just allocate an array of pointers initialized to nullptr:
auto varfuri = new Point*[nbcorners]{};
in which you consider nullptr a replacement of the default-constructed state and then you construct and add elements with new:
varfuri[i] = new Point(/*constructor arguments*/);
Make sure to delete every individual element and delete[] the array allocation when you are done.
This does however also have different semantics than an array of directly allocated elements would have. However it seems more reasonable as an assignment.
And none of these new uses would be considered ok in practice, because they are not going to behave correctly in the presence of exceptions. Instead one would at least wrap both allocations in std::unique_ptrs (if std::vector cannot be used for whatever reason).
Or (since C++17) you can allocate an array of std::optionals and consider the empty state of the std::optional as replacement for the default-constructed state. But I have the feeling that this isn't allowed by your instructor either.
i trying to implement the following link http://in.mathworks.com/help/vision/examples/motion-based-multiple-object-tracking.html in opencv and c++.
I have created a class say ex:
class assign
{
vector <int> id;
vector <int> area;
vector<Point> centroid;
};
After this i have created an object
assign id;
Now i want to assign the centroid value and other values too. what i tried is
id.centroid (p);
where p is a "point" But i'm getting error for this. I don't know where i'm going wrong.
centroid is a private member of class assign. If you want to access it directly, you should make it public
class assign
{
public:
vector<Point> centroid;
//...
};
And if you want to add a Point into centroid, you should
id.centroid.push_back(p);
The main answer is already given by songyuanyao. What I want to add is a possible solution which allows you to use the member variables like you already tried it.
If you want to get and set the member centroid with id.centroid(p) you could go with the following class declaration:
class Assign
{
public:
vector<Point> centroid();
void centroid(vector<Point> c);
private:
vector<Point> m_centroid;
};
The definition might then look like this:
// getter
vector<Point> Assign::centroid() {
return m_centroid;
}
// setter
void Assign::centroid(vector<Point> c) {
m_centroid = c;
}
Now if you use id.centroid(p) to set the member the overloaded setter will be called and will set the variable. If you call p = id.centroid() (empty parameter list) the overloaded getter will be called and will return the current m_centroid.
To add to the previous answers; if you want to expand on your class this can be done for you during construction of your object.
class Assign {
private:
std::vector<int> m_vIds;
std::vector<int> m_vAreas;
std::vector<Vec2> m_vCentroids;
public:
Assign(); // Default Constructor Same As What You Have But Not Declared.
Assign( int* pIds, int* pAreas, int* pCentroids ); // Create By Using Pointers
// Create By Passing In Either Pre Filled Vectors Or Even An Empty
// Vectors To Be Filled Out Later. Passes By Reference. This Will
// Also Set The Variables That Are Passed In From The Caller.
Assign( std::vector<int>& vIds, std::vector<int>& vAreas, std::vector<Vec2>& vCentroids );
// Since You Are Using Vectors Within This Class It Is Also Good To
// Have A Destructor To Clear These Out Once The Object Is Done And
// Ready To Be Destroyed Or Removed From Memory
~Assign();
};
// The Destructor Would Look Like This
Assign::~Asign() {
if ( !m_vIds.empty() ) {
m_vIds.clear();
}
if ( !m_vAreas.empty() ) {
m_vAreas.clear();
}
if ( !m_vCentroids.empty() ) {
m_vCentroids.empty();
}
} // ~Assign
// NOTE: I used Vec2 instead of point due to my use of programming
// 2D & 3D Graphics Rendering Engines; Most Graphics APIs and Libraries
// along with Most Math Libraries Will Not Have A Point Class; Most Will
// Use Vec2 or Vec3 - Vector2 or Vector3 & Vector4 Since in terms of
// memory they are exactly the same thing. It is up to you to know which
// objects are points or locations, and which are vectors as in forces,
// velocities, accelerations, directions, normals etc. The only major
// difference between a discrete Point Class or Structure versus a Vector
// Class is that the Vector Class usually has operations defined with it
// to do vector mathematics such as addition, subtraction, multiplication by
// value, multiplication by vector, division by value, division by vector,
// cross & dot product, comparisons, testing if vector is 0, setting it to
// be a normal vector, returning the magnitude or length and a few others.
// The general point class or object is usually just data values or
// simply coordinates without operations.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am really struggling with using functions and classes, and on VS, I get a "Matrix::Matrix()" is unaccessible error, and I just cannot figure out why.
I'm trying to learn about functions and classes and just am not getting it! The program basically uses a constructor and destructor in a class called Matrix, and creates a 'matrix'. I am now trying to use a function within this matrix class to get the value from inside of the constructed Matrix, and it will return the correct value, but don't understand why I am getting this error.
#include <iostream>
using namespace std;
class Matrix
{
Matrix();
private:
int M;
int N;
double *data;
int get(int i, int j){
return data[i*N+j];
}
//CONSTRUCTOR
public:
Matrix(int sizeR, int sizeC,double * input_data)
{
M=sizeR;//Rows
N=sizeC;//Columns
data = new double[M*N];//creation of 1D array, uses m&n values
cout<<"\nMatrix::Matrix(int sizeR, int sizeC, double * input_data) is invoked\n\n";
//ENTER DATA INTO MATRIX HERE:
for(int i=0;i<M*N;i++)//Loops for every data entry into 1D array, uses r&c as referenece to size
data[i] = input_data[i];//Accesses each value at specific location, inputs value 'val'
for(int i=0;i<M*N;i++)//Loops for every data entry into 1D array
cout<<data[i]<<" ";
}
//DECONSTRUCTOR
~Matrix(){
//delete data
delete []data;
cout<<"\n\nMatrix::~Matrix() is invoked\n\n";
}
};
int main()
{
int sizeR, sizeC, g1, g2;
g1 = 2;
g2 = 2;
Matrix M1;
cout<<"Enter No. Rows: ";
cin>>sizeR;
cout<<"Enter No. Columns: ";
cin>>sizeC;
double * input_data;
input_data = new double[sizeR*sizeC];
//INPUTS VALUES TO ARRAY
for(int i=0;i<sizeR*sizeC;i++)//Loops for every row
input_data[i] = i+1*input_data[i-1];
Matrix(sizeR, sizeC, input_data);
cout<<"Find value at row: ";
cin>>sizeR;
cout<<"Find value at column: ";
cin>>sizeC;
M1.get(g1, g2);
}
The default access modifier for classes in C++ is private so if you didn't explicitly used the public: access modifier before the definition of the constructor Matrix() then it would be considered to be private.
You want to create M1 object using the constructor you provided.
The line Matrix(sizeR, sizeC, input_data); doesn't create M1 object.
You need to do Matrix M1(sizeR, sizeC, input_data); or create the default constructor with public accessibility.
Furthermore (as somebody pointed out) M1.get(...) will also cause errors if Matrix::get() is not public.
Just place your default constructor (declaration/definition) in your class' public section:
class Matrix {
public: // <<<<
Matrix() {
}
Matrix(int sizeR, int sizeC,double * input_data) {
// ...
}
// ...
};
The default scope policy for class is private unless specified differently.
There is no definition of the constructor which takes no parameters, and further its declaration is private. Therefore, the call
Matrix M1;
fails. Just provide a definition in your class such as
Matrix() {}
and make that public accessible and it will work fine.
EDIT: The get function as well need to be public. Next, this raw array is a bad thing which leeds to a double-free corruption error. Use a std::vector instead. This becomes code-review, I guess. See here for a still quick-n-dirty but somewhat improved implementation.
I am making a battleships game for my coursework, and I have run into some problems with the get functions in one of the classes I am using. The basic idea of my game is to create a 2D 10X10 array, called grid, filled with null pointers to represent the board. I have created 2 classes, Board and Ship. The grid array is of type Ship, and I use an algorithm to fill the array with Ships randomly. I use the Board class to access the grid array and the hits array (which I use to track hits).
However I cannot figure out how the getShips function can return the grid array. The hits array is just booleans so that was easy enough, but I am not proficient enough at C++ to make the getShips function properly return the grid array, which is a Ship pointer type. I would greatly appreciate any help.
class Board
{
private:
Ship *grid[10][10];
bool hits[10][10];
public:
// get functions
Ship *getShips()
{
return grid;
}
bool getHits()
{
return hits;
}
};
I was also wondering if it would be possible to manipulate the array in other functions by calling the getShips function. Something like:
for (int x=0; x<10; x++)
{
for (int y=0; y<10; y++)
{
board.getShips()[x][y]=nullptr;
}
}
Ok. First I would modify the getShips and getHits functions. To have something like that :
Ship *getShips(int x, int y){ return grid[x+y*10]; }
bool getHits(int x, int y){return hits[x+y*10];}
That way you'll simplify your code and avoid some errors.
When you declare a multidimensional array like you do with
Ship *grid[10][10];
bool hits[10][10];
you're basically declaring pointers to pointers to pointers to ships.
I would try to use a minimum amount of pointers if you're writing in C++. Try to use the stl containers instead. They do automatic memory management for you which may save you some time down the road.
I suggest to change your interface to something like:
class Board
{
private:
Ship *grid[10][10];
bool hits[10][10];
public:
Ship* getShip(int x, int y) const { return grid[x][y]; }
Ship*& getShip(int x, int y) { return grid[x][y]; }
bool getHit(int x, int y) const { return hits[x][y]; }
bool& getHit(int x, int y) { return hits[x][y]; }
};
If you really want to return grid and hits, I recommend to use std::array<std::array<Ship*, 10>, 10> grid; (require C++11) instead of Ship *grid[10][10];.
if C++11 is not possible turn back to std::vector.
and then
private:
std::array<std::array<Ship*, 10>, 10> grid;
public:
const std::array<std::array<Ship*, 10>, 10>& getShips() const { return grid; }
std::array<std::array<Ship*, 10>, 10>& getShips() { return grid; }
Currently, it looks like getShips is returning the entire 10x10 array of Ship*-- you need to change what the getShips function is returning:
Ship*** getShips() { ...
However, I would recommend against mixing pointers and arrays. Pointers can be tricksy, and combining with arrays can get very difficult to debug. Instead, you could use all pointers: Ship ***grid; and initialize with new (I'll leave the initialization as an exercise, but here's a site that has an example: http://pleasemakeanote.blogspot.com/2010/07/2d-arrays-in-c-using-new.html).
In reality, it might be better for the Ship class to store the indices of where it exists, perhaps something like this:
class Ship
{
public:
<<member func>>
private:
int nspaces_;
int start_[2];
int end_[2];
}
where you store the beginning index and the final index where the ship is found. You'll need to handle the code to identify the spaces between, but that is trivial. This setup would allow you to replace Ship *grid[10][10] with a single array of Ships.
The getShips function would then become:
...
Ship ships_[<<number of ships>>];
Ship *getShips()
{
return ships_;
}
...
and would be used:
board.getShips()[x][y]
Or...you could add a getShip(int x, int y) method.