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];
}
Related
Wrote a simple program. You write a number in the console and an array with the size of the number you wrote in is created and printed. I have now this error, heap corruption detected and I see no problems with my code so please help me out.
#include <iostream>
class dmas
{
public:
int num;
dmas(int size)
{
this->num = size;
}
int* a = new int[num];
void logic()
{
for (int i = 0; i < num; i++)
{
a[i] = rand() % 100;
}
}
void print()
{
for (int i = 0; i < num; i++)
{
std::cout << a[i] << std::endl;
}
delete [] a;
}
};
int main()
{
srand(time(NULL));
int size;
std::cout << "Enter the size of the massive" << std::endl;
std::cin >> size;
dmas a(size);
a.logic();
a.print();
return 0;
}
The problem is this initialization of the pointer a
class dmas
{
public:
int num;
dmas(int size)
{
this->num = size;
}
int* a = new int[num];
//...
The call of the operator new occurs when the variable num is default initialized and has no yet the value of the parameter size assigned to it in the body of the constructor.
At least you need to write
dmas(int size) : num( size )
{
}
Pay attention to that the call of operator delete []
delete [] a;
you should move from the function print to the class destructor.
Let's check the value of num at the allocation.
I added a function
int printNum(int num) {
std::cout << "num = " << num << std::endl;
return num;
}
and changed the allocation
int* a = new int[num];
to
int* a = new int[printNum(num)];
This resulted in num = 0 being printed despite of I entered 10 for the standard input.
Now you can see the value of num set in the constructor is not used here.
To fix this, you can use member initializer:
dmas(int size) : num(size)
{
}
You don't allocate any memory at all, because this int* a = new int[num]; is outside the scope of your constructor!
To make it work, replace this piece of code:
public:
int num;
dmas(int size)
{
this->num = size;
}
int* a = new int[num];
with this:
public:
int num;
int *a;
dmas(int size)
{
this->num = size;
a = new int[num];
}
Then should work fine!
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;
}
my homework assignment is asking me to create a array2d class and I am having trouble compiling it. It crashes every time it is compiled and I am unsure what I am doing wrong. My debugger is saying it is during my set value portion but I am not sure what it is exactly. Help would be great!
#include <iostream>
using namespace std;
class array2D {
private:
int xRes, yRes;
float **xtable;
public:
array2D(int xRes, int yRes){
float **xtable;
xtable = new float*[yRes];
for(int i=0;i < yRes;i++) {
xtable[i] = new float[xRes];}}
~array2D(){
for (int i = 0; i<yRes; i++){
delete [] xtable[i];}
delete [] xtable;}
void getSize(int &xRes, int &yRes){}
int getValue (int x, int y){return xtable[x][y];}
void setValue(int x, int y, int Val) {xtable[x][y]=Val;}
};
int main() {
array2D *a = new array2D(320,240);
int xRes, yRes;
a->getSize(xRes,yRes);
for(int i=0;i < yRes;i++){
for(int j=0;j < xRes;j++){
a->setValue(i,j,100); // constant value of 100 at all locations
}
}
for(int i=0;i < yRes;i++){
for(int j=0;j < xRes;j++){
cout << a->getValue(i,j) << " ";
}
cout << endl;
}
delete a;
}
In these lines
array2D(int xRes, int yRes){
float **xtable;
you are declaring a local variable. The class member variable of the same name remains uninitialized and you use that later.
Remove the second line.
Also, the member variables xRes and yRes are not initialized either.
Use:
array2D(int xResIn, int yResIn) : xRes(xResIn), yRes(yResIn) {
xtable = new float*[yRes];
for(int i=0;i < yRes;i++) {
xtable[i] = new float[xRes];
}
}
Also, change
void getSize(int &xRes, int &yRes){}
to
void getSize(int &xResOut, int &yResOut)
{
xResOut = this->xRes;
yResOut = this->yRes;
}
As you expand this class, keep in mind The Rule of Three and implement the copy constructor and copy assignment operator.
array2D(array2D const& copy) { ... }
array2D& operator=(array2D const& rhs) { ... }
I have a class named Test and I'd like to create empty 2D array that will hold instances of that class and than add them later one by one using constructor that accepts parameters.
Basically, I'd just like to reserve memory that I will fill in later with objects. It needs to bee on a heap since I will have class that will generate 2D arrays of different sizes.
This was my first approach but it doesn't really work since Test class doesn't have default constructor:
Test** arr;
arr = new Test*[10];
for (int i = 0; i < 10; i++)
arr[i] = new Test[10];
[EDIT]
Here is my full test code. All in all, I'm getting wrong values out, it should be numbers from 0 to 99:
#include <iostream>
using namespace std;
class Test {
private:
short number;
public:
Test(short n) {
this->number = n;
}
short getNumber() {
return number;
}
};
int main() {
Test** arr;
arr = new Test*[10*10];
for (int i = 0; i < 100; i++)
arr[i] = new Test(i);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++)
cout << arr[i][j].getNumber() << " ";
cout << endl;
}
}
Maybe try using a default constructor with default parameters?
Test(int i = 0) {. . .}
Assume I have a class A that has say 3 methods. So the first methods assigns some values to the first array and the rest of the methods in order modify what is computed by the previous method. Since I wanted to avoid designing the methods that return an array (pointer to local variable) I picked 3 data member and store the intermediate result in each of them. Please note that this simple code is used for illustration.
class A
{
public: // for now how the class members should be accessed isn't important
int * a, *b, *c;
A(int size)
{
a = new int [size];
b = new int [size];
c = new int [size];
}
void func_a()
{
int j = 1;
for int(i = 0; i < size; i++)
a[i] = j++; // assign different values
}
void func_b()
{
int k = 6;
for (int i = 0; i < size; i++)
b[i] = a[i] * (k++);
}
void func_c()
{
int p = 6;
for int (i = 0; i < size; i++)
c[i] = b[i] * (p++);
}
};
Clearly, if I have more methods I have to have more data members.
** I'd like to know how I can re-design the class (having methods that return some values and) at the same time, the class does not have the any of two issues (returning pointers and have many data member to store the intermediate values)
There are two possibilities. If you want each function to return a new array of values, you can write the following:
std::vector<int> func_a(std::vector<int> vec){
int j = 1;
for (auto& e : vec) {
e = j++;
}
return vec;
}
std::vector<int> func_b(std::vector<int> vec){
int j = 6;
for (auto& e : vec) {
e *= j++;
}
return vec;
}
std::vector<int> func_c(std::vector<int> vec){
//same as func_b
}
int main() {
std::vector<int> vec(10);
auto a=func_a(vec);
auto b=func_b(a);
auto c=func_c(b);
//or in one line
auto r = func_c(func_b(func_a(std::vector<int>(10))));
}
Or you can apply each function to the same vector:
void apply_func_a(std::vector<int>& vec){
int j = 1;
for (auto& e : vec) {
e = j++;
}
}
void apply_func_b(std::vector<int>& vec){
int j = 6;
for (auto& e : vec) {
e *= j++;
}
}
void apply_func_c(std::vector<int>& vec){
// same as apply_func_b
}
int main() {
std::vector<int> vec(10);
apply_func_a(vec);
apply_func_b(vec);
apply_func_c(vec);
}
I'm not a big fan of the third version (passing the input parameter as the output):
std::vector<int>& func_a(std::vector<int>& vec)
Most importantly, try to avoid C-style arrays and use std::vector or std::array, and don't use new, but std::make_unique and std::make_shared
I'm assuming you want to be able to modify a single array with no class-level attributes and without returning any pointers. Your above code can be modified to be a single function, but I've kept it as 3 to more closely match your code.
void func_a(int[] arr, int size){
for(int i = 0; i < size; i++)
arr[i] = i+1;
}
void func_b(int[] arr, int size){
int k = 6;
for(int i = 0; i < size; i++)
arr[i] *= (k+i);
}
//this function is exactly like func_b so it is really unnecessary
void func_c(int[] arr, int size){
int p = 6;
for(int i = 0; i < size; i++)
arr[i] *= (p+i);
}
But if you just want a single function:
void func(int[] arr, int size){
int j = 6;
for(int i = 0; i < size; i++)
arr[i] = (i+1) * (j+i) * (j+i);
}
This solution in other answers is better, if you are going to allocate memory then do it like this (and test it!) also if you are not using the default constructor and copy constructor then hide them, this will prevent calling them by accident
class A{
private:
A(const &A){}
A() {}//either define these or hide them as private
public:
int * a, *b, *c;
int size;
A(int sz) {
size = sz;
a = new int[size];
b = new int[size];
c = new int[size];
}
~A()
{
delete[]a;
delete[]b;
delete[]c;
}
//...
};