I'm doing this A class which has a vector of B's. I'm initializing the vector on the constructor of the A class (I'm not sure if this is the right way, but it compiles). Besides this, I'm having a problem because I don't want that when initializing the vector that it initializes himself with the default construtor of B() because this makes me do a for loop to set the value that I want. It would be fine if the vector position stood NULL or stood 0 to size;
class B{
int _t;
public:
B(){ _t = 1; }
B(int t) : _t(t){}
};
class A{
std::vector<B> _b;
public:
A(int size): _b(size){
for(int i = 0; i < size; i++){
_b[i].setNumber(i);
}
};
int main() {
int n = 3;
A _a(n);
return 0;
}
You can simply let the vector be default constructed (empty), then emplace_back into it:
A(int size) {
_b.reserve(size);
for(int i = 0; i < size; i++){
_b.emplace_back(i);
}
}
If you are stuck with a pre-C++11 compiler, you can push_back B objects into it:
A(int size) {
_b.reserve(size);
for(int i = 0; i < size; i++){
_b.push_back(B(i));
}
}
The calls to std::vector::reserve are to avoid re-allocations as the vector grows in size.
It does not compile. class B does not have a setNumber function. Initializing the vector to a size does not require you to do anything. It would just default construct number of objects equal to the specified size. Vector has a reserve member function that allows you to allocate enough memory for some number of elements without actually constructing objects. Perhaps that is what you were seeking. Obviously leaving it empty until you are ready to perform some form of insertion is another option. Hopefully one or more of the posted answers will help.
class A{
std::vector<B> _b;
public:
A(int size){
_b.reserve(size);
}
};
Related
I need to declare a 2D array as the member variable of a class. I can't use STL (so, no vector), and I've been asked to avoid double/triple pointers. I want to be able to reference elements in this 2D array using subscripting notation, e.g. arr[0][0]. The array also must be declared on the heap due to its size.
Due to the requirements I have, none of the existing answers on StackOverflow meet my needs.
What I've been trying to do is:
class MyClass {
public:
MyClass() : arr(new int[1000][2]) {}
// other stuff here
private:
int arr[1000][2];
};
The error I get after compiling that class is "cannot initialize a parameter of type int * with an lvalue of type int[1000][2]". Clearly, I can solve this by using pointer syntax, but, as mentioned above, I've been asked to use "array syntax" for code clarity. I was hoping someone with a better understanding of C++ could explain how to use "array syntax".
Of course you can do this without double/triple pointers. You can even do this without use of any pointers in the class declaration. But first lets look at the more common approach. A 2D array is a simple extension of a 1D array.
Starting off with the standard way this is done for a 1D array of 1000 ints w/o using vector. The pointer, arr, is on the stack but points to an array of 1000 ints on the heap.
class MyClass {
public:
MyClass() : arr(new int[1000]) {}
private:
int *arr;
};
Elements are accessed the usual way. For instance arr[0]=42;
Extending this to a 2D array in the heap is a simple extension of the above.
You need to declare the member variable as a pointer to a 1D array instead of the basic type.
class MyClass {
public:
MyClass() : arr(new int[1000][2]) {}
private:
int (*arr)[2];
};
Similarly, you can refer to elements of the 2D array the usual way: arr[0][0]=42;
Finally, there is the approach that completely eliminates pointers except the one required for the new. Here we initialize a reference. The trick is to add a third level to new, the [1] so that the *new returns an object that is the actual 2D int array. Structurally, it is no different than what the pointer version above does but lets us directly initialize a reference to a 2D int array. It's certainly not a common idiom so I'd stick with the ptr approach.
class MyClass {
public:
MyClass() : arr(*new int[1][1000][2]) {}
~MyClass() {delete[] arr;}
//private: // to test
int(&arr)[1000][2];
};
int main()
{
MyClass obj;
obj.arr[2][1] = 42;
}
When your class has an array in it, and you use new to create a new instance of that class, that array is on the heap. You can still access the array with arr[i][j].
Why not do something like this?
class myClass {
public:
int arr[1000][2];
};
int main() {
myClass* test = new myClass;
for (int i = 0; i < 1000; i++) {
for (int j = 0; j < 2; j++) {
test->arr[i][j] = 5;
}
}
}
You can use 2 classes to achieve this.
class BaseArray {
public:
int& operator[](int x) { return this->arr[x]; }
int operator[](int index) const { return this->arr[index]; }
int arr[2];
};
class myClass {
public:
myClass() {}
~myClass() {}
BaseArray& operator[](int index) { return this->arr[index]; }
BaseArray operator[](int index) const { return this->arr[index]; }
BaseArray arr[1000];
};
Optionally use can use templates to make this class more dynamic.
template<class TYPE, int arraySize>
class BaseArray {
public:
TYPE& operator[](int x) { return this->arr[x]; }
TYPE operator[](int index) const { return this->arr[index]; }
TYPE arr[arraySize];
};
template<class TYPE, int dim1, int dim2>
class myClass {
public:
myClass() {}
~myClass() {}
BaseArray<TYPE, dim2>& operator[](int index) { return this->arr[index]; }
BaseArray<TYPE, dim2> operator[](int index) const { return this->arr[index]; }
BaseArray<TYPE, dim2> arr[dim1];
};
int main()
{
myClass<int, 1000, 2> myArray;
}
EDIT
When you provide the array dimentions int arr[1000][2]; the variable will automatically be allocated in the stack. If the array needs to be fully dynamic, you can just use a double pointer int** arr = { nullptr }; and initialize it at the constructor as shown below.
class myClass {
public:
myClass()
{
arr = new int* [1000];
for (int i = 0; i < 1000; ++i)
arr[i] = new int[2];
}
~myClass()
{
/* Make sure to delete or else it might flag a memory error. */
for (int i = 0; i < 1000; ++i)
delete[] arr[i];
delete[] arr;
}
int** arr = { nullptr };
};
I got stuck with deleting an dynamically allocated array of int.
I've got a destructor, where I'm trying to use a loop for to delete all elements of array and finally delete it.
I have code on http://rextester.com/OTPPRQ8349
Thanks!
class MyClass
{
public:
int _a;
int* c;
int fRozmiar;
static int fIlosc;
MyClass() //default constructor
{
_a=0;
c = new int [9];
for(int i = 0; i<=9; i++)
{
c[i] = 1;
}
fIlosc++;
}
MyClass(int a1, int c1) // parametrized constructor
{
_a=a1;
c = new int [c1];
for(int i = 0; i<=c1; i++)
{
c[i] = rand();
}
fIlosc++;
}
MyClass(const MyClass &p2) // copy constructor
{
_a =p2._a;
c = p2.c;
fRozmiar = p2.fRozmiar;
fIlosc = fIlosc;
fIlosc++;
}
~MyClass(); // destructor
static int getCount() {
return fIlosc;
}
};
//Initialize static member of class
int MyClass::fIlosc = 0;
MyClass::~MyClass()
{
for(int i = 0; i<sizeof(c); ++i)
{
delete[] c[i];
}
delete[] c;
fIlosc--;
}
int main()
{
}
Remove the for-loop, but keep the delete[] c after it.
Each int doesn't need to be deleted because they're not dynamically allocated. If you needed to delete them, then the for-loop wouldn't work becuase: sizeof(c) is not the size of the array, and delete[] should have been delete instead.
There are several problems in the code.
First, that loop in the destructor must go. If you didn’t new it, don’t delete it.
Second, a loop through an array of N elements should be for (int i = 0; i < N; ++i). Note that the test is i < N, not i <= N. The loops as currently written go off the end of the array. That’s not good.
Third, the copy constructor copies the pointer. When the first object goes out of scope its destructor deletes the array; when the copy goes out of scope its destructor also deletes the array. Again, not good. The copy constructor has to make a copy of the array. In order to do that the class needs to also store the number of elements the array.
Beginner in C++
I have a class, say
class A
{
public:
int N;
double .....
};
But I would like the ..... to define a matrix of size depending on N. In case that changes the approach, it is a non-identical function of N and not just N itself, say N^3+1.
In case that is the approach, I have never written a constructor of an object in C++. Therefore, if this is the approach could you please give some detail. I don't understand how it might work. When the class is instanciated, maybe the property N hasn't been even initialized.
I am not clear how to get a matrix or array (I am still not clear of the basic data types of C++) of size determined in execution.
Edit: The value of N is determined later in the code. It is something like:
A InstanceOfA; //The variable InstanceOfA is declared of type A.
...
Some other stuff happens, e.g. other properties of InstanceOfA are initialized
and some of the functions are used. And then:
...
A.setN(4);
I didn't understand from the answer below. Would I need to do
A InstanceOfA(4);
?
You can use std::vector
class A
{
public:
int N; // you should use int for size
double std::vector<std::vector<double>> matrix; //define the matrix
//initialize it in the constructor
A( int size ):N(size), matrix(size*3+3)// or you can use any expression that evaluates an integral value
{
//you can initialize the values in matrix here
}
};
Note
the expression matrix(size*3+3) initializes the matrix such that, there are size*3+3 rows, the number of columns in each row are not specified yet. You can also specify column sizes in the constructor like
for( int i=0;i< N*3+3; ++i) //for each row
{
matrix[i].resize(N*2);// resize each col to hold N*2 cells,
}
Edit
As per the modification in question, you can then leave the constructor empty (or initialize any other members), and provide a setSize method in class A, which will later initialize the size.
void setSize(int size){
N= size;
matrix.resize( size*3+3);
for( int i=0;i< N*3+3; ++i) //for each row
{
matrix[i].resize(N*2);// resize each col to hold N*2 cells,
}
}
Then you can use it like:
A instanceOfA;
//other code
//
instanceOfA.setSize(N);
You can use an std::vector<std::vector<double>> to capture the matrix. Also, change the type of N to int.
class A
{
public:
int N;
std::vector<std::vector<double>> matrix;
};
Define a constructor and initialize the data in the constructor.
class A
{
public:
A(int n) : N(n)
{
int matrixSize = N*N*N+1;
for (int i = 0; i < matrixSize; ++i )
{
matrix.push_back(std::vecotr<double>(matrixSize));
}
}
double N;
std::vector<std::vector<double>> matrix;
};
One possible way is to do it with a pointer. If you only allocate your array in constructor and its size will not change during the lifetime of your object, that could be done in this way:
class A
{
public:
double N;
double* arr;
A(double aN):N(aN)
{ arr = new double[3*N+1]; // allocate your array in constructor
... // do whatever else you need to initialize your object
}
...
~A() { delete[] arr;} // free it in destructor
...
}
See also the tutorial on Dynamic Memory.
You will then instantiate your class in one of two ways:
A a(aN);
// this object will be automatically destroyed when it gets out of scope, for example at the end of the function where it was created
A* a = new A(aN);
// this object will have to be deleted by yourself when it's no longer needed:
...
delete a;
If you don't know N at the moment when you create your object, you can postpone the allocation :
class A
{
public:
double N;
double* arr = NULL;
A() { ... } // do whatever you need in your constructor
setN(double aN)
{
N = aN;
arr = new double[3*N+1]; // allocate your array
}
...
~A() { if(arr) delete[] arr;} // free your array in destructor if needed
...
}
then you can call your object as:
A a;
In C++ how initialize all values of a member array for a class?
#define MAX_MATRIX 20
Class Matrix {
public:
Matrix(); //constructor
protected:
int n[MAX_MATRIX]; // note cannot do = { 0} or w/e here
};
Matrix::Matrix()
{
// how to set all n to -1?
}
You can use std::fill:
std::fill(begin(n), end(n), -1);
(These begin and end functions can be found in namespace std in C++11, or you can easily implement them yourself in C++03)
This was a glaring shortcoming of C++03. In C++11 this has been fixed, and you can now initialize everything, including arrays:
class Matrix
{
public:
Matrix() : n { } { }
protected:
static const unsigned int MAX_MATRIX = 20;
int n[MAX_MATRIX];
};
(The nasty preprocessor macro is also not needed in C++.)
In C++03, you simply cannot initialize an array member, but you can set it to something meaningful in the constructor body, e.g. via std::fill(n, n + MAX_MATRIX, 0);.
(Of course it would be a lot nicer to say std::array<int, MAX_MATRIX> n;.)
There's a type for this:
class Matrix {
public:
Matrix() : n() { n.fill(-1); }
protected:
std::array<int, 20> n;
};
for (unsigned i = 0; i < MAX_MATRIX; ++i) n[i] = -1;
#include <cstring>
...
Matrix::Matrix()
{
static bool init=false;
static int n_init[MAX_MATRIX];
if (!init){
for(int i=0; i<MAX_MATRIX; i++){
n_init[i] = -1;
}
init = true;
}
memcpy(n,n_init,MAX_MATRIX*sizeof(int));
}
The array n_init is initialized exactly once and stored in memory, then all subsequent constructions are a quick memory copy with no loops. You should not see much decrease in speed if you increase the size of MAX_MATRIX as you would when looping through the index, particularly if you are calling Matrix::Matrix() many times.
I'm writing a class for the Arduino. It's been going well so far, but I'm sort of stuck now...
I have declared an int array in my class
class myClass
{
public: MyClass(int size);
private:
int _intArray[];
};
When I initialize the class MyClass myClass1(5) I need the array to look like this {0,0,0,0,0}.
My question: what do I need to do so that the array contains 'size' amount of zeros?
MyClass::MyClass(int size)
{
//what goes here to dynamically initialize the array
for(int i=0; i < size; i++) _intArray[i] = 0;
}
Edit: Following up on various replies below, Arduino does not include the standard library so unfortunately std::vector is not an option
Your code as I'm writing this:
class myClass
{
public: MyClass(int size);
private:
int _intArray[];
};
The declaration of _intArray is not valid C++: a raw array needs to have a size specified at compile time.
You can instead instead use a std::vector:
class myClass
{
public:
MyClass( int size )
: intArray_( size ) // Vector of given size with zero-valued elements.
{}
private:
std::vector<int> intArray_;
};
Note 1: some compilers may allow your original code as a language extension, in order to support the "struct hack" (that's a C technique that's not necessary in C++).
Note 2: I've changed the name of your member. Generally underscores at the start of names can be problematic because they may conflict with names from the C++ implementation.
Cheers & hth.,
You should use a std::vector.
class myCLass {
public:
myClass(int size)
: intarray(size) {
for(int i = 0; i < size; i++) intarray[i] = 0;
}
private:
std::vector<int> intarray;
};
You should really use vectors as others have suggested. A work-around could be as shown (in case you do not want to use memcpy or a loop).
This would be useful if you have a really huge array. Note that it would add a level of indirection to access the array.
class myClass
{
public:
myClass(){
mt = T(); // value initialize.
}
private:
struct T{
int _intArray[10];
} mt;
};
int main(){
myClass m;
}
I'll try the following:
class myClass
{
public:
MyClass(int size);
~MyClass();
private:
int* _intArray;
};
MyClass::MyClass(int size) {
_intArray = new int[size];
for (int i=0; i<size; ++i) _intArray[i] =0; // or use memset ...
}
MyClass::~MyClass() {
delete[] _intArray;
}
Or, even better, use a STL vector instead ...
you can use another hack basing on a string value and then populate a limited size array
check this :
https://github.com/Riadam/ViewPort-Array-Shifter-for-Arduino-Uno.git