0

I'm writting Matrix class and got to the point where I need to create an array of Array objects, but Array can't have constructor with no arguments ( it need m argument to allocate memory for it ). I searched and haven't found the solution, people only sugest doing it with Vector object, but I am not allowed to do it with anything other than arrays. Then a friend sent me the constructor for matrix that works for them, but even they don't know why it works.

Matrix::Matrix(int n, int m):n(n),m(m) {
    srand(time(0));
    this->data=new Array(n);
    for(int i=0; i<n; i++){
        this->data[i].m=this->m;
        this->data[i].data=new int[m];
        for(int j=0; j<this->m; j++){
            this->data[i].data[j]= rand()%10; 
        }
    }
}

I don't get how this this->data[i] is defined? [] operator isn't overloaded anywhere and data is only a single Array object not an array of Array-s. So why and how is this working and not an compile error?

Source files:

Header:

#define ROK04_ROK04_H

class Array{
protected:
    int* data;
    int m;

public:
    Array(int m);
    Array& operator = (const Array& a);
    virtual ~Array();
    Array& operator+=(const Array& a);
    virtual void setElem(int pos, int value);
    virtual void print() const;
    friend class Matrix;
};

class Matrix{
protected:
    Array* data;
    int n;
    int m;
public:
    Matrix(int n, int m);
};

#endif //ROK04_ROK04_H ```

#ifndef ROK04_ROK04_H
#define ROK04_ROK04_H

class Array{
protected:
    int* data;
    int m;

public:
    Array(int m);
    Array& operator = (const Array& a);
    virtual ~Array();
    Array& operator+=(const Array& a);
    virtual void setElem(int pos, int value);
    virtual void stampa() const;
    friend class Matrix;
};

class Matrix{
protected:
    Array* data;
    int n;
    int m;
public:
    Matrix(int n, int m);
    void stampaj();

};

#endif //ROK04_ROK04_H 

Cpp:

#include <iostream>
#include <ctime>
#include "rok04.h"
using namespace std;

Array::Array(int m):m(m),data( new int[m]() ){}

Array& Array::operator=(const Array& a) {
    cout << "Usao" << this << endl;
    for(int i = 0; i < m; i++){
        data[i] = a.data[i];
    }

    return *this;
}

Array::~Array() {
    delete[] data;
}

void Array::setElem(int pos, int value) {
    try {

        if(pos >= m){
            cout << "Usao\n";
            throw out_of_range("Index out of bounds!");
        }

        data[pos] = value;

    } catch (out_of_range& oor){
        cerr << oor.what() << endl;
    }
}

void Array::print() const {
//    cout << m;
    for (int i = 0; i < m; ++i) {
        cout << data[i] << " ";
    }
    cout << endl;
}

Array &Array::operator+=(const Array& a) {

    int* temp = new int(m+a.m);

    for(int i = 0; i < m; i++){
        temp[i] = data[i];
    }

    for (int i = m; i < m+a.m; ++i) {
        temp[i] = a.data[i-m];
    }

    delete[] data;
    data = temp;
    m = m+a.m;

    return *this;
}

Matrix::Matrix(int n, int m):n(n),m(m) {
    srand(time(0));
    this->data=new Array(n);
    for(int i=0; i<n; i++){
        this->data[i].m=this->m;
        this->data[i].data=new int[m];
        for(int j=0; j<this->m; j++){
            this->data[i].data[j]= rand()%10;
        }
    }
}
6
  • 2
    this->data is not an object of class type - it's a pointer to Array. this->data[i] uses the built-in [] operator - it accesses ith element in the (plain) array of Array objects that data points to. Except that data only actually points to a single object, so this->data[i] exhibits undefined behavior whenever i != 0, by way of accessing an index out of bounds. Commented Jan 9, 2022 at 22:54
  • 3
    In this case, this->data[i] is performing pointer arithmetic, it is identical to *(this->data + i) Commented Jan 9, 2022 at 22:55
  • The constructor doesn't work. this->data=new Array(n); looks like a typo for this->data=new Array[n]; which would create n objects of type Array, but this->data=new Array(n); creates only one. this->data=new Array[n]; doesn't work for you though, since Array requires an argument for construction. Commented Jan 9, 2022 at 22:58
  • If you are expected to use only new and not the standard library, then the only easy way out of this is to define a default constructor for Array which initializes the pointer to nullptr, and then you can assign the actual fully constructed Array objects in a loop. Commented Jan 9, 2022 at 23:00
  • Related: stackoverflow.com/questions/4622461/… Commented Jan 9, 2022 at 23:01

1 Answer 1

2

You have this definition: int* data. So by default, given a pointer operand, data[x] is translated into *(data + x) by the C++ compiler.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.