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.
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.
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))
);
}
i'm having problems creating a destructor for a template class that has a private 2d dynamic array. for some reason the destructor destroys the matrix as soon as i am done entering information into the matrix. not sure what went wrong since it compiles fine but gives an error when i enter the info for the first 2 matrices and the program tries to multiply them. the code works if i get rid of the destructor.
template <class T>
class matrix
{
//sudo
friend matrix operator + , *,-,(bunch of friends used to overload)
//end sudo
public:
matrix(): rows(0), cols(0){}
int Arows(){return rows;}
int Acols(){return cols;}
class Proxy
{
matrix& _a;
int _i;
public:
Proxy(matrix& a, int i) : _a(a), _i(i){}
int& operator[](int j) {return _a.Array[_i][j];};
};
Proxy operator[](int i) {return Proxy(*this,i);}
~matrix();
private:
T ** Array;
int rows;
int cols;
};
template<class T>
matrix<T>::~matrix()
{
for (int i=0;i<rows;i++)
delete [] Array[i];
delete [] Array;
}
It is hard to tell without seeing the exact code and calling code, but it might be because you are missing copy constructor and assignment operator.
matrix m1;
{
matrix m2 = ...
m1 = m2; // copy ctor, now they share same Array pointer
} // m2 destructor free the Array
// m1 is left with dangling Array pointer
from the code sample it doesn't seem like real code. Where is Array initialized, what is matrixArray?
I think the comment provided by R. Martinho Fernandes answers it... I wanted to point something else out and I'm doing it as an answer purely so I can format code.
People get obsessed with doing lots of memory allocations just to make a 2D array... But it's slow! If you are doing a lot with these matrices, you will be better off doing a single memory allocation. It goes a bit like this:
Array = (T**)malloc( rows*sizeof(T*) + rows*cols*sizeof(T) );
T* rowData = (T*)(Array + rows);
for( int r = 0; r < rows; r++ ) {
Array[r] = rowData;
rowData += cols;
}
And when you want to free this memory:
free((void*)Array);
Naturally, I assume that you're using basic types... In fact you might be better off using typename T instead of class T in the template.
Oh yeah, this makes it really easy to copy data from one matrix (of the same size) to another. You just allocate as above and then do a single memcpy on the data section.
My question is how to access and modify a 2D array defined in one class that is friends with another class. Below are some details on my question:
In class A I declare and allocate the appropriate space for my 2D array (pointer-to-pointer) u.
Class A
{
public:
friend class B;
long double **u;
int fun;
void make();
};
void A::make()
{
long double **u = new long double *[nx];
for (int i=0;i<nx;i++)
u[i] = new long double [ny];
int fun = 9;
}
Class A is friends with Class B; I need to use the array I declared in Class A in a function defined in class B. Below is my Class B:
class B
{
public:
void get(A*);
};
void B::get(A *pt)
{
using namespace std;
cout << pt->fun;
cout << pt->u[0][0];
}
I get a Bus error on my second cout pt->u[0][0]. Is there a simple way to use this setup I have to access my u[][] array? I think that I get the error because the pointer points to the 1st entry of my array, thus my whole 2D array is saved in memory as a single row (thinking aloud here). I'm a Fortran guy so this stuff is a little new to me.
Any help or "pointers" to other helpful threads would be appreciated.
Thank you !
Alberto
I think you get error because A::u is not initialized ( in method A::make you initialize a local variable u, not member. You need to change
void A::make()
{
long double **u = new long double *[nx]; // should be just u, or this->u.
There are some problems with your code: nx and ny don't seem to be defined anywhere, and in make you don't initialize A::fun at all, you instead set a local variable named fun which goes out of scope immediately.
As for your error, it sounds like the error stems from the fact that make() has not been called on pt. Ensure that make() is called on the instance you pass to get, otherwise the array u will not be allocated.