Double declaration and initialization of vector in a class, C++? - c++

Good night dear all
I have a question, look i working with classes and in many cases i am using vectors of vector (2D vectors), my code runs quite well. However, i am a bit confused, look in my header file i declared a vector of vectors in my protected variables, then in my cpp file in the constructors section i declared again the vector of vectors, but this time giving the needed sizes and having "0" in all the elements. However, when i tried to use this vector of vectors in my member function, it seems that not dimension was delcared and not "0" values, if i use .size() the output is "0" and i was expecting 3.
However, when i declare again the vectors of vectors in the member (see commented line in the cpp file) function the code gives the 3 and the full matrix which is a 3 X 3, composed by "0".
Why is that? using the constructor is to bassically give the values of the variables.
See the next code, the commented line on the cpp file is on which i have declare again the vector.
the header file is:
#pragma once
#include <iostream>
#include <vector>
class Matrix
{
private:
const int m_nRows;
const int m_nCols;
protected:
std::vector <std::vector <double>> MATRIX;
public:
Matrix(int rows, int cols);
~Matrix();
void getMatrix();
};
The cpp file is:
#include "Matrix.h"
Matrix::Matrix(int rows, int cols)
: m_nRows(rows),
m_nCols(cols)
{
std::vector <std::vector <double>> MATRIX(m_nRows, std::vector<double>(m_nCols, 0));
}
Matrix::~Matrix()
{
}
void Matrix::getMatrix()
{
//std::vector <std::vector <double>> MATRIX(m_nRows, std::vector<double>(m_nCols, 0));
std::cout << MATRIX.size() << std::endl;
for (auto& columns : MATRIX)
{
for (auto& element : columns)
{
std::cout << element << " ";
}
std::cout << "\n";
}
}
The main file is:
#include <iostream>
#include <vector>
#include "Matrix.h"
int main() {
int rows = 3;
int cols = 3;
Matrix SmallMatrix(rows, cols);
SmallMatrix.getMatrix();
system("pause>0");
}

In your constructor:
Matrix::Matrix(int rows, int cols)
: m_nRows(rows),
m_nCols(cols)
{
std::vector <std::vector <double>> MATRIX(m_nRows, std::vector<double>(m_nCols, 0));
}
you define a brand new variable with the name MATRIX, which is totally distinct from the member variable Matrix::MATRIX.
To initialize the Matrix::MATRIX member variable you should do it in the member initializer list, jut like for the m_nRows and m_nCols variables:
Matrix::Matrix(int rows, int cols)
: m_nRows(rows),
m_nCols(cols),
MATRIX(m_nRows, std::vector<double>(m_nCols, 0))
{
}

You are declaring another variable named MATRIX in the constructor. You have to instead use resize() on the MATRIX member declared in the class. The initialization of that MATRIX can be like this:
MATRIX.resize(m_nRows);
for (int i =0; i<m_nRows; i++){
MATRIX[i].resize(m_nCols, 0);
}

Related

Adding a member to std::vector<std::vector<int>> class in C++

I have to modify a code so that I can add a member to 2D vectors.
The code started with a typedef vector<vector<int>> Matrix which I replaced with a Matrix class.
I tried to inherit from vector<vector<int>> using :
class Matrix: public vector<vector<int>> {
public:
int myMember;
};
This way I practically don't have to modify the source code much.
However, if I try to run :
Matrix mymatrix (4);
It raises an error :
modele.cpp:19:20: error: no matching function for call to 'Matrix::Matrix(int)'
Matrix mymatrix (4);
^
In file included from modele.cpp:8:0:
modele.h:6:7: note: candidate: Matrix::Matrix()
class Matrix: public vector<vector<int>> {
^
modele.h:6:7: note: candidate expects 0 arguments, 1 provided
Constructors are not inherited by default, but can use them in your derived class for that you have to do something like this:
#include <vector>
#include <iostream>
class Matrix : public std::vector<std::vector<int>>{
public:
using vector::vector;
int myMember;
};
int main(){
Matrix data(1);
std::vector row = {1,2,3,4,5};
data.push_back(row);
for(auto i: data){
for(auto r : i){
std::cout << r << std::endl;
}
}
}
This way compiler will know all the constructors from the base class. And will call the appropriate constructor for your derived class.

How to declare a global 2d 3d 4d ... array (heap version) variable that could be used in the entire program?

class1.cpp
int a=10; int b=5; int c=2;
//for this array[a][b][c]
int*** array=new int**[a];
for(int i =0; i<a; i++)
{
array[i] = new int*[b];
for(int k =0; k<b; k++)
{
array[i][k] = new int[c];
}
}
how can i use this array in other .cpp files ?
Instead of manually allocating an array you should at least use a std::vector. What you would do is have a header file that contains
extern std::vector<std::vector<std::vector<int>>> data;
that you will include in all the cpp files you wish to share the vector with and then in a single cpp file have
std::vector<std::vector<std::vector<int>>> data = std::vector<std::vector<std::vector<int>(a, std::vector<std::vector<int>>(b, std::vector<int>(c)));
and now you will have a global object that is shared and it has a managed lifetime.
You shouldn't really use a nested vector though. It can scatter the data in memory so it isn't very cache friendly. You should use a class with a single dimension vector and pretend that it has multiple dimensions using math. A very basic example of that would look like
class matrix
{
std::vector<int> data;
int row; // this really isn't needed as data.size() will give you rows
int col;
int depth;
public:
matrix(int x, int y, int z) : data(x * y * z), row(x), col(y), depth(z) {}
int& operator()(int x, int y, int z) { return data[x + (y * col) + (z * col * depth)]; }
};
and then the header file would be
extern matrix data;
and a single cpp file would contain
matrix data(a, b, c);
Prefer std::array or std::vector to raw arrays. You had constant dimensions so use std::array.
Declare it in header file:
// header.h
#pragma once // or use multiple inclusion guards with preprocessor
#include <array>
const int a = 10;
const int b = 5;
const int c = 2;
using Array3D = std::array<std::array<std::array<int,c>,b>,a>;
extern Array3D array3d; // extern indicates it is global
Define it in cpp file:
// class1.cpp
#include "header.h"
Array3D array3d;
Then include the header wherever you want to use it.
// main.cpp
#include "header.h"
int main()
{
array3d[3][2][1] = 42;
}
I am not sure I have understood what exactly you mean but simply :
class1 obj1;
obj1.array[i][j][k] // assuming you make the array public and already initialized in the constructor(and dont forget to delete it in the destructor)

Read Matrix from file, give it to main

I have a fairly simple program. It reads a matrix from a file that looks like this
4 4
a b c d
a b c d
a b c d
a b c d
and outputs it in the console. The program is working as intended:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
int n, m;
ifstream myfile;
myfile.open ("matrix.txt");
myfile >> n >> m;
char mat[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
myfile >> mat[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << mat[i][j];
}
cout << endl;
}
return 0;
}
Now this program is going to grow a lot, so I want to start using headerfiles and declare the functions external so that my main looks more like
int main() {
readMat();
printMat();
}
My Problem is, I don't really know how to do this right. Where should I declare the matrix so that both functions can "see" it? I can't declare it globally as char mat[n][m] because I only know n and m inside readMat().
Or is my whole design flawed and there is much better way to do this?
I would be grateful for every little tip.
I have not worked with multiple files in c++ yet.
You cannot use an array like that, when not just multiple translation units, but multiple functions are involved.
Any function needs to know the exact data types it receives as parameters, and this must be declared at compile time.
Here, you don't know the type of the array until runtime. array[10] and array[15] are different types. Don't be fooled by the fact their name might be the same. It's not the name that matters, but the type, like int [10] or int [11].
You have two basic options:
Use templates.
Convert your array to a std::vector<std::vector<int>>. Then you can declare the array (now a vector) globally, and/or pass it as a parameter to your multiple functions.
Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
namespace mynamespace {
template <class T>
class Matrix {
private:
int m_rows;
int m_columns;
T** m_data;
public:
Matrix(); // Default Constructor - Null or Empty Matrix
Matrix( const int rows, const int columns ); // Empty Matrix With Defined Size
Matrix( const int rows, const int columns, const T** data ); // Defined Matrix
T** getData() const;
}; // Matrix
#include "Matrix.inl"
} // mynamespace
#endif // MATRIX_H
Matrix.inl
// Matrix Constructor and Function Implementations Here
Matrix.cpp
#include "Matrix.h"
Main.cpp
#include <string>
#include <iostream>
#include <fstream>
#include "Matrix.h"
using namespace mynamespace;
void readMatrix( std::fstream& fin, const std::string& strFilename, Matrix& matrixIn );
void printMatrix( const Matrix& matrix );
int main() {
std::fstream fileIn; // Prefer to not use "using namespace std;"
std::string strFilename( "Matrix.txt" );
Matrix<type> mat(); // Default Empty Matrix To Be Filled In
readMatrix( fileIn, strFilename, mat );
printMatrix( mat );
return 0;
} // main
void readMatrix( std::fstream& fin, const std::string& strFilename, Matrix& mat ) {
// Do Work Here To Populate Matrix Object
} // readMatrix
void printMatrix( Matrix& mat ) {
// Do Work Here To Print Matrix Being Passed In
} // printMatrix
With this pseudo code, the design here allows any type of matrix to be constructed. The matrix is an object of a template type. The implementation of generating a matrix by reading in data from a file, and the implementation of displaying or printing that matrix are independent of the class itself. This allows for the matrix class to be as generic as possible without having to rely on any other libraries. The functions that do the work are stand alone functions that accept a matrix object. A modification may be needed in your text or binary file to work with this construct.
matrix.txt
type
4 4
a b c d
a b c d
a b c d
a b c d
The only problem with this, is it should already be obvious: you need to define what type of data this matrix will hold when instantiating it. Yet you do not know the type until after you read the file in. So this code does have a bug in it that would need to be address. However, the overall design method used here is to only show how to keep similar code objects contained with in their own class object while separating independent code blocks that does work on them. Now other class objects may have a file reading and print methods, but normally Vector (math & not containers) and Matrix classes usually don't.

C++ Creating a Matrix of Sets

I am trying to create a Matrix of Sets in C++ but I get an error that there is no matching function to call. Here is my code:
supermercat.hh
#ifndef SUPERMERCAT_HH
#define SUPERMERCAT_HH
#include <vector>
#include <iostream>
#include <set>
#include "producte.hh"
using namespace std;
class supermercat
{
private:
vector <vector <set <producte> > > estructura;
public:
// Constructores
supermercat();
//Modificadores
void crear_estructura(int col, int fil);
void repostar_estanteries(producte prod, string lloc);
supermercat.cc
#include "supermercat.hh"
supermercat::supermercat() {}
void supermercat::crear_estructura(int col, int fil)
{
vector <vector <set <producte> > > estructura(col, vector<producte>(fil));
}
void supermercat::repostar_estanteries(producte prod, string lloc)
{
estructura[lloc[0] - 'A'][lloc[1] - 1].insert(prod);
}
Does anyone know what I am doing wrong? I just can't figure it out.
I tried to do it as a matrix of vectors in the past but it as kind of annoying to sort each vector in the matrix (as I need 'productes' to be ordered alphabetically).
I think that the problem is your crear_estructura method implementation. In the base class (supermercat), you have the private member:
vector <vector <set <producte> > > estructura;
In the implementation part, you try to execute following:
vector <vector <set <producte> > > estructura(col, vector<producte>(fil));
and it is not defined elsewhere (to me, this line is a declaration, it does not implement anything).
Also, the input:
vector<producte>(fil)
in previous definition is rather strange. Did you mean to use square brackets, i.e. [] instead of ()? E.g. vector<producte> prods[fill].
As your solution is somewhat tricky, I'd suggest to simplify it a bit. The quick solution is to make a new class estructura (fill in as appropriate):
class estructura
{
private:
vector <vector <set <producte> > > _mestruct;
public:
estructura(int col, vector<producte> fil);
~estructura();
}
and then implement constructor to fit your requirements. After that, use it in the supermercat class like this:
class supermercat
{
private:
estructura structdata;
public:
... (like before)
}
and your supermercat constructor implementation should be like this:
void supermercat::crear_estructura(int col, vector<producte> fil)
{
estructura(col, fil);
}
I hope this will help you a bit to solve the problem.
The problem you have is with the vector initialization, you should use resize() to resize the first dimension and then resize for each item to resize the other dimension of the vector, here is a simple example that does that:
#include <iostream>
#include <vector>
#include <set>
std::vector< std::vector< std::set<int> > > test;
int main()
{
test.resize(100);
// if not c++11 replace with for (i = 0; i < 100; ++i) test[i].resize(100)
for (auto &a: test)
a.resize(100);
test[20][20].insert(1);
test[30][30].insert(1);
test[30][30].insert(2);
std::cout << "(20,20): " << *test[20][20].begin() << std::endl;
std::cout << "(30,30): size " << test[30][30].size() << std::endl;
}
Using this syntax in your "create_estructura" method it should be something like:
void supermercat::crear_estructura(int col, int fil)
{
estructura.resize(col);
for (auto &a: estructura) a.resize(fil);
}
Every item in "estructura" will contain an empty set.

Declaring vector size in a class

I am supposed to write a program that simulates a dice(6 faced) roll 6000 times and stores the results in a vector. For example if the dice roll returns 1, I would do something like frequency.at(0)++. Since the size of the vector is gonna be fixed, and I would also need to able to access each element freely, I was wondering if there was anyway to declare the size of the vector using a default constructor or something. This is what I currently have but I get a "too many arguments in function call" and "expression must have class type" error. Maybe what I'm trying to do is not possible, I don't know, but just looking for some help. Thanks.
My header file:
#ifndef AHISTOGRAM_H
#define AHISTOGRAM_H
class aHistogram
{
public:
aHistogram();
~aHistogram();
void update(int face);
void display(int maxLengthOfLine);
void clear() const;
int count(int face);
private:
vector<int> numRolls();
int numx, m, j;
};
#endif
aHistogram.cpp:
#include <iostream>
#include <cstdlib>
#include <vector>
#include "aHistogram.h"
using namespace std;
aHistogram::aHistogram()
{
numRolls(6);
numx, m, j = 0;
}
aHistogram::~aHistogram()
{
}
void aHistogram::update(int face)
{
numRolls.at(face - 1)++;
return;
}
This is what the constructor's initializer list is for:
aHistogram::aHistogram(): numRolls(6), numx(0), m(0), j(0) // constructor parameters here
{
// numRolls(6);
// numx m, j = 0;
}
Also the declaration of your vector is wrong in your class definition:
class aHistogram
{
public:
aHistogram();
~aHistogram();
void update(int face);
void display(int maxLengthOfLine);
void clear() const;
int count(int face);
private:
// vector<int> numRolls(); // this is declaring a function!
vector<int> numRolls; // USE THIS!!
int numx, m, j;
};
IF the size of the "vector" is fixed, then using std::array is most certainly a better option, unless of course, you are using an ancient compiler which doesn't support C++11.
Go through the above link on cppreference.com. For most part, it is just like an "old fashioned" array, but it also comes with benefits such as bounds checking (if you use at() instead of operator[]), ability to iterate through elements (begin(), end(), etc.), and many other "benefits" of std::vector.
Have a look at this:
#include <iostream>
#include <array>
using namespace std;
class aHistogram {
public:
aHistogram() : numRolls{0, 0, 0, 0, 0, 0} {}
int count(int face) {
return numRolls.at(face - 1);
}
void update(int face) {
numRolls.at(face - 1)++;
}
private:
array<int, 7> numRolls;
};
int main() {
aHistogram ah;
ah.update(1);
ah.update(2);
ah.update(1);
cout << "Count[1]: " << ah.count(1) << " Count[2]: " << ah.count(2) << endl;
}