Defining methods and field of an Array in a class - c++

I would like to be able to build a class where I have an array of integers. I have just made a simple code, but it's not printing the elements of the array.
The code compiles, but I don't have any results.
#include <iostream>
using namespace std;
const int len = 5;
class TrialArray {
protected:
int len;
int A[];
public:
TrialArray() {
for (int i=0; i<this->len; i=i+1) {
this->A[i] = i;
}
}
void print() {
for (int i=0; i<this->len; i=i+1) {
std::cout << this->A[i] << '\t';
}
}
};
int main() {
TrialArray A;
A.print();
return 0;
}
It's a simple code. in the main, I have the method, A.print() and it should print the values, 0,1,2,3,4 in this case but it's not. And I am not understanding where I might be doing wrong.

You are referencing the this->len variable in the constructor instead of the global static len.
Also you have not specified the size of the array.
You need to change your code to properly reference the global variable. A better way to do this is to provide the size of the TrialArray in the constructor.
Change the int A[] to int *A and dynamically allocate it with new.
Store the size given to the constructor in this->len, and then populate the array as you have done.
Like this:
#include <iostream>
using namespace std;
class TrialArray
{
protected:
int len;
int *A;
public:
TrialArray(int size)
{
A = new int[size];
this->len = size;
for (int i=0; i<this->len; i=i+1)
{
this->A[i] = i;
}
}
void print() {
for (int i=0; i<this->len; i=i+1)
{
std::cout << this->A[i] << '\t';
}
}
};
int main()
{
TrialArray A(5);
A.print();
return 0;
}

Related

C++ program behavior on pointers to integer array

Can anyone please explain why the loop only execute once!!
The for loop executes once and never reaches end of the programm
and if you've got some time to review my mistakes then please point out mistakes because i know this is not how it is done!!
using namespace std;
#include<iostream>
int* rotate(int* ar,int d,int n)
{
int tmp[n];
d = d%n;
for (int i = 0; i < n; ++i)
{
tmp[i] = ar[(i+d)%n];
}
free(ar);
return tmp;
}
int main(int argc, char const *argv[])
{
int arr[] = {1,2,3,4,5};
int *a;
int n = sizeof(arr)/sizeof(arr[0]);
a = rotate(arr,4,n);
cout<<endl;
for (int i = 0; i < n; ++i)
{
cout<<i<<endl;
cout<<a[i]<<endl;
}
cout<<"End";
return 0;
}
Lets take it apart...
int* rotate(int* ar,int d,int n)
{
int tmp[n]; // 1
d = d%n;
for (int i = 0; i < n; ++i)
{
tmp[i] = ar[(i+d)%n];
}
free(ar); // 2
return tmp; // 3
}
int tmp[n]; is not standard C++. If you do not want to use std::vector the proper replacement would be a dynamically allocated array.
You call free with a pointer that was not allocated via malloc, which invokes undefined behavior. In C++ you shouldn't be using free and malloc at all, but rather new and delete. And also new and delete only for such exercise. Otherwise use smart pointers.
You return a pointer to a local variable. The pointer is dangling and using it in main invokes undefined behavior.
You can't simply replace the static array arr in main with something else in the function. A function called rotate is not expected to create a new array or delete the one that was passed (also because like in your case it is just not possible).
There are different ways to fix your code. I choose to make rotate rotate the array "in-place". However, as you can see, the implementation actually uses an additional array of same size. I leave it to you to figure out how to change it to use less additional memory:
#include <iostream>
using std::cout;
using std::endl;
void rotate(int* ar,int d,int n)
{
int* tmp = new int[n];
d = d%n;
for (int i = 0; i < n; ++i)
{
tmp[i] = ar[(i+d)%n];
}
for (int i = 0; i < n; ++i)
{
ar[i] = tmp[i];
}
}
int main(int argc, char const *argv[])
{
int arr[] = {1,2,3,4,5};
int n = sizeof(arr)/sizeof(arr[0]);
rotate(arr,4,n);
cout<<endl;
for (int i = 0; i < n; ++i)
{
cout<<i<<endl;
cout<<arr[i]<<endl;
}
cout<<"End";
return 0;
}
This is how you can do the same using std::rotate:
#include <array>
#include <iostream>
#include <algorithm>
int main(int argc, char const *argv[])
{
int arr[] = {1,2,3,4,5};
int n = sizeof(arr)/sizeof(arr[0]);
std::rotate(std::begin(arr),std::begin(arr)+4,std::end(arr));
for (int i = 0; i < n; ++i)
{
std::cout << i << std::endl;
std::cout << arr[i] << std::endl;
}
std::cout<<"End";
}
... it even uses pointers ;)

Why is move constructor used over copy constructor?

This is simple program that is supposed to handle a dynamic array of numbers and then to filter out the elements that are even and put them into a new array and then print both arrays on the screen.
This is the header file:
#pragma once
namespace filter
{
class Array
{
double *arr;
int n;
public:
Array();
Array(int);
Array(const Array&);
Array(Array&&);
void PutIn();
void PrintOut() const;
Array isEven();
Array filter(const std::function<bool(int)>&) const;
~Array();
};
}
Then, this is the implementation of functions:
#include <iostream>
#include <functional>
#include "Array.h";
using namespace filter;
using namespace std;
Array::Array() :arr(nullptr), n(0)
{ }
Array::Array(int n)
{
this->n = n;
arr = new double[n];
}
Array::Array(const Array &a1)
{
n = a1.n;
arr = new double[n];
for (int i = 0; i < n; i++)
arr[i] = a1.arr[i];
}
Array::Array(Array &&a1)
{
n = a1.n;
for (int i = 0; i < n; i++)
arr[i] = a1.arr[i];
a1.n = 0;
a1.arr = nullptr;
}
void Array::PutIn()
{
cout << "Insert elements:\n";
for (int i = 0; i < n; i++)
cin >> arr[i];
}
void Array::PrintOut() const
{
cout << "\nYour array is :\n";
for (int i = 0; i < n; i++)
cout << arr[i] << "\t";
}
Array Array::isEven()
{
return filter([](int x) { return x % 2; });
}
Array Array::filter(const std::function<bool(int)> &f) const
{
int b = 0;
for (int i = 0; i < n; i++)
if (f(arr[i]) == 0)
b++;
Array temp(b);
b = 0;
for (int i = 0; i < n; i++)
if (f(arr[i]) == 0)
{
temp.arr[b] = arr[i];
b++;
}
return temp;
}
Array::~Array()
{
delete[]arr;
n = 0;
}
Finally, this is the source code:
#include <iostream>
#include <functional>
#include "Array.h"
using namespace filter;
using namespace std;
int main()
{
Array a(5);
a.PutIn();
Array b = a.isEven(); //WHY THIS LINE OF CODE INVOKES MOVE CONSTRUCTOR AND NOT COPY CONSTRUCTOR?
a.PrintOut();
b.PrintOut();
getchar();
getchar();
}
So, as you can see, this is relatively simple program that needs to handle an array with five elements in it entered by user and then to create a new array that consists of even elements of the first array. When i run this, it works fine, however, there is one little thing that i don't understand here.
If you look at the source code, notice the line where i left my comment, that is the line where move constructor is called, but i don't know why. That would mean that a.IsEven() is a RVALUE, since move constructor works with RVALUES, right? Can anyone explain me why this is rvalue and what is the correct way to understand this? Any help appreciated!
Your assumption that calling isEven invokes your move constructor is not in fact correct. Nor does it invoke your copy constructor. Instead, RVO ensures that the object returned is constructed directly at the calling site so neither is required.
Live Demo (which doesn't address any of the flaws in your code mentioned in the comments).

How to pass and return 3d array to a function in c++?

I have created a 3d array into main function because one of its size came from used input. I am using C++
std::cin >> size;
typedef int T[8][3];
T* tables = new T[size];
It is basically tables[size][8][3]
Now I have to use this 3d table in different functions and have to store values into it. The best way to do it by make this table as a global variable. But I am not sure that I can do it after main function. The other option I have, that I have to pass this table as a parameter and have to return that at the end of the function.
I have tried both the approach but I am having error. Please help me about this issue. I don't know which approach to choose and how to do it.
Thank you in advance.
**Example:**This an example what I really want to do. Here I create a 3d array in main function and through another function I gave some input into that array and again print that in main function.
#include <iostream>
#include <conio.h>
using namespace std;
class M
{
public:
int i,j,k;
public:
int pass(int (*table)[8][3],int size);
}
int M:: pass(int (*table)[8][3],int s)
{
for (i=0;i<s;i++)
{
//int a = tables[i][2][1];
for(j=0;j<8;j++)
{
for(k=0;k<3;k++)
{
table[i][j][k]=i;
}
}
}
return (*table)[8][3]; // not sure about this
}
int main()
{
int size,i,j,k;
std::cin >> size;
typedef int T[8][3]; // T is your 2d array type
T* tables = new T[size];
cout << "test";
M mx;
mx.pass(tables,size); // not sure
for (i=0;i<size;i++)
{
for(j=0;j<8;j++)
{
for(k=0;k<3;k++)
{
cout<<tables[i][j][k];
cout<<" ";
}
cout<<endl;
}
cout<<endl;
cout<<"..........." << i <<endl;
}
getch();
}
I don't know if I completely understand your problem. But you can definitely store the pointer locally in your object and reference it elsewhere. Something like this:
class M
{
public:
M(int(*tbl)[8][3]) : table(tbl) { }
int(*table)[8][3];
int i, j, k;
public:
void pass(int size);
};
void M::pass(int s)
{
for (i = 0; i<s; i++)
{
for (j = 0; j<8; j++)
{
for (k = 0; k<3; k++)
{
table[i][j][k] = i;
}
}
}
}
int main()
{
int size, i, j, k;
std::cin >> size;
typedef int T[8][3]; // T is your 2d array type
T* tables = new T[size];
cout << "test";
M mx(tables);
mx.pass(size); // not sure
for (i = 0; i<size; i++)
{
for (j = 0; j<8; j++)
{
for (k = 0; k<3; k++)
{
cout << tables[i][j][k];
// or you can also:
// cout << mx.table[i][j][k];
cout << " ";
}
cout << endl;
}
cout << endl;
cout << "..........." << i << endl;
}
_getch();
}
Since you are creating a dynamic 3D array whose two dimensions are fixed, Use a std::array<std::array<int, 3>, 8> as your 2D array. Use a std::vector<__2D_ARRAY_TYPE> to create the 3D array.
#include <iostream>
#include <array>
#include <vector>
int main() {
std::array<std::array<int, 3>, 8> array_2d ;
std::vector<decltype(array_2d)> array_3d ;
int size = 4 ;
for(int i = 0; i < size; ++i)
{
for(int j = 0; j < 8; ++j)
for(int k = 0; k < 3; ++k)
array_2d[j][k] = j + k ;
array_3d.push_back(array_2d);
}
return 0;
}
Something like this you can use easily which does the job more easily without any manual memory management.
You can pass it to a function. The signature would be :
return_type function_name(const std::vector<std::array<std::array<int, 3>, 8>>& array_3d)
{ .... }
In
class M
{
public:
int i,j,k;
public:
int pass(int (*table)[8][3],int size);
}
you don't have to write public twice. You can simply put all of the public member data under the keyword public.
Also, you seem to be re-writing your function over again at the very end. Instead of
cout<<tables[i][j][k];
You can write
cout<<*tables

How to make multiple instances of a class in C++

How do you create multiple class instances without individually typing in their names?
int main(){
myClass myInstance_1;
myClass myInstance_2;
myClass myInstance_3;
...
myClass myInstace_10;
}
You may do the following:
int main(){
std::vector<myClass> myInstances;
for(int i = 0; i < 10; ++i) {
myInstances.emplace_back(i);
}
myInstances[5].myClassFunction();
}
How do you create multiple class instances without individually typing in their names?
The answer is you make an array, but not the way you tried it.
Like this:
int main()
{
MyClass myInstance[10];
for(int i = 0; i < 10; i++)
{
myInstance[i].myClassFunction();
}
}
TIP: Don't use arrays, use std::vector or std::array.
(see answer from #Jarod42)
Solution 1: Use an array of integers as an initializer, the constructor is used to convert the integer to myClass.
class myClass
{
public:
//constructor
myClass( int num) {m_number = num;};
void myClassFunction(){cout<< "I am " << m_number << endl;}
private:
int m_number;
};
int main(){
myClass myInstance[10] = {0,1,2,3,4,5,6,7,8,9};
for ( int i=0; i< 10; i++) myInstance[i].myClassFunction();
}
Solution 2: Use a static counter to set m_number, so no need to use a non-default constructor.
class myClass
{
public:
//constructor
myClass(){m_number=counter++;};
void myClassFunction(){cout<< "I am " << m_number << endl;}
private:
int m_number;
static int counter;
};
int myClass::counter = 0;
int main(){
myClass myInstance[10];
for ( int i=0; i< 10; i++) myInstance[i].myClassFunction();
}
Solution 3: Set the m_number after the constructor call, so the default constructor is enough.
class myClass
{
public:
//constructor
void setNum(int num){m_number=num;};
void myClassFunction(){cout<< "I am " << m_number << endl;}
private:
int m_number;
};
int main(){
myClass myInstance[10];
for ( int i=0; i< 10; i++) myInstance[i].setNum(i);
for ( int i=0; i< 10; i++) myInstance[i].myClassFunction();
}
Just like Jarod42's code:
int main(){
std::vector<myClass> myInstances;
for(int i = 0; i < 10; ++i) {
myInstances.push_back(myClass(i));
}
myInstances[5].myClassFunction();
}
I think these should work.
Use array:
myClass myInstance[10];
This will create an array with 10 instances but each instance will have its m_number set to 0.
Another approach:
myClass *myInstance = new myClass[10];
for (unsigned int i = 0; i < 10; i++)
{
myInstance[i] = new myClass(i);
}
Here each instance will have different m_number values
Edit for the sake of fixing the problem with above code. Better solutions have already been proposed.
myClass *myInstance[10];
// Allocate
for (unsigned int i = 0; i < 10; i++)
{
myInstance[i] = new myClass(i);
}
// At the end free
for (unsigned int i = 0; i < 10; i++)
{
delete myInstance[i];
}

c++ function that fills array

What I'm trying to do:
User inputs two numbers.
Array is declared using those numbers as dimensions.
Function outside main() is filling the array.
Array is accessed in main() for further thingies.
What I have problem with:
Function + array combination doesn't seem to work as I think.
What I did:
void tablica1(int h, int w)
{
int m,n;
for(m=0; m<h; m++)
for(n=0; n<w; n++)
{
arr[h][w]=1;
}
}
What happens:
array arr is inaccessible in tablica1() because it has not been declared in that function.
Of course, when I declare the array in tablica1() it becomes inaccessible in main().
Possible solutions:
Passing arr to tablica1() as a reference - no idea how to do that
Declaring arr in tablica1() and somehow passing it to main() - no idea how to do that
Other possible solutions?
You can declare the array outside of both, at compilation unit level:
int arr[10][10];
void func() {
for (int i=0; i<10; i++) {
for (int j=0; j<10; j++) {
arr[i][j] = i + j;
}
}
}
int main(int argc, const char *argv[]) {
func();
std::cout << arr[3][4] << "\n"; // Output will be 7
return 0;
}
If you want handle a dynamically-sized matrix the most common pattern is to use an std::vector of std::vectors (it's a little more general and therefore a little less efficient than a 2d matrix because each row can have a different length, but in most cases the cost difference is not a big issue)
#include <vector>
std::vector< std::vector< int > > arr;
void func() {
int height = arr.size();
int width = arr[0].size();
for (int i=0; i<height; i++) {
for (int j=0; j<width; j++) {
arr[i][j] = i + j;
}
}
}
int main() {
int height = 13;
int width = 7;
arr = std::vector< std::vector<int> >(height, std::vector<int>(width));
func();
...
}
the two solutions you mentioned
1、Passing arr to tablica1() as a reference
void tablica1(int h, int w,int **arr)
{
int m,n;
for(m=0; m<h; m++)
for(n=0; n<w; n++)
{
arr[h][w]=1;
}
}
void main()
{
const int h=100,w=100;
int arr[h][w];
tablica1(h,w,arr);
}
2、Declaring arr in tablica1() and somehow passing it to main()
int **tablica1(int h, int w)
{
int m,n;
int **arr=new int*[h];
for(int i=0;i<h;i++)
{
arr[i]=new int[w];
}
//it is best to initialize arr by setting each element 0
for(m=0; m<h; m++)
for(n=0; n<w; n++)
{
arr[h][w]=1;
}
return arr;
}
void main()
{
const int h=100,w=100;
int **arr=tablica1(h,w);
//do somting
//delete arr
for(int i=0;i<h;i++)
{
delete []arr[i];
}
delete []arr;
}
If you want to declare a dynamic multidimensional array you can do that with the template give below.
#include<iostream.
#include <vector>
using namespace std;
typedef vector<int> vi;
vector<vi> arr; // arr is a dynamic two dimensional array.
vi.assign(10,vi());//10 rows of type vi .
If you want to enter values in arr you can do that by
vi[0].push_back(a);
vi[0].push_back(b); // a,b,c are some example values..
vi[1].push_back(c);
You can understand using this code
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
typedef vector <int> vi;
vector<vi> arr;// dynamic multidimensional array
int main(){
cout<<"enter array size\n";
int h,w,temp;;
cin>>h>>w;
arr.assign(h,vi());
int i, j;
for(i=0; i < h ;i++)
for(j=0; j < w; j++)
{
cin>>temp;
arr[i].push_back(temp);
}
// for printing
for(i=0; i < h ;i++){
for(j=0; j < w; j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
return 0;
}