0

What i want to do: I want to know how to use classes as a kind of 'built-in' arrays in C++(C is also acceptable). So, basically I want to be able to do this:

array1d rows(5); 
//an integer array of length 5 - iniatilized to 0 upon instantiation.
//rows can be imagined as this: [ 0, 0, 0, 0, 0 ]



array1d x(1), y(2), z(3);
array2d cols(3);
cols[0] = x;
cols[1] = y;
cols[2] = z;

//an array of array of integers [ [x] [y] [z] ]
//where x, y and z are of type array1d, so here is what it would like:
//if x = 1, y = 2, z = 3
//[ [0], [0, 0], [0, 0, 0] ]

array3d depth(2); 

//an array of array of array of integers [ [cols] [cols] ]
//where cols is of type array2d, so when expanded it would like:
//[ [ [0], [0, 0], [0, 0, 0] ]
//  [ [0], [0, 0], [0, 0, 0] ] ]

What I have so far

using namespace std;

class array3d;
class array2d;

class array1d//works exactly the way i want it to 
{
    int len;
    int *data;
public:
    array1d (int size){
        data = new (nothrow) int[size];

        if (data != 0){
            len = size;

            for (int i = 0; i<len; i++){
                data[i] = -1;
            }
        }
    }

    ~array1d (){
        delete data;
    }


    void print(){
        for (int i = 0; i<len; i++){
                cout << data[i] << " ";
            }
        cout << endl;
    }


    int operator[] (int index){
        if (index >= 0 && index <= len){
            return data[index];
        }
    }


    friend class array2d;
};

class array2d//this is what needs changing
{
    int len;
    array1d *data;
public:
    array2d (int size_dim1, int size_dim2){
        data = new (nothrow) array1d[size_dim1]; //i think the problem is here

        if (data !=0){
            len = size_dim1;
            for (int i = 0; i < len; i++){
                data[i] = array1d(size_dim2);
            }
        }
    }
    ~array2d (){}

    void print(){
        for (int i = 0; i < len; i++){
            data[i].print();
        }
    }

    array1d operator[] (int index){
        return data[index];
    }

    friend class array3d;   
};

class array3d//dont even know how to get this one started
{
    array3d (int size_dim1, int size_dim2, int size_dim3){
             data = new (nothrow) array2d[size_dim2, size_dim3]; 

        if (data !=0){
        len = size_dim1;
            for (int i = 0; i < len; i++){
                data[i] = array2d(size_dim2, size_dim3);
            }
        }
            }
    ~array3d (){}
    //overload [] operator

private:
    int len;
    array2d *data;
};

I also want to be able to add more classes to accomodate for a possible 4 dimension such that i dont have to customize each and every time i add another class.

7331skillz
  • 141
  • 1
  • 6

3 Answers3

0

You can't put different type of items into an array. But in your case, since your 2d class contains 1d class, 3d class contains 2d class, you can do it like this:

class array1d
{
  // something
};

class array2d : public array1d
{
  // something
};

class array3d : public array2d
{
  // something
};

and put pointers into an array.

array1d *arr[3];
arr[0] = new array1d;
arr[1] = new array2d;
arr[3] = new array3d;
Rango
  • 1,087
  • 7
  • 5
0

Your classes are memory leak generators... Every time you call new ... have a think about who has to be in charge to call delete!

That said, it is not clear if you want arrays to by dynamic (sized at runtime) or static (sized on declaration, just like the built in are).

In this last case, a starightforward sample can be this one:

#include <iostream>

template<class T, size_t... Z>
class array; //not defined: just a varadic template forward

template<class T, size_t A>
class array<T,A> //simple case for 1D
{
public:
    array() :m() {}
    array(const T& a) :m(a) {}
    T& operator[](int i) { return m[i]; }
    const T& operator[](int i) const { return m[i]; }

private:
    T m[A];
};

template<class T, size_t A, size_t... Z>
class array<T,A,Z...> //case for multi Dim as 1D of Dim-1
{
public:
    array() :m() {}
    array<T,Z...>& operator[](int i) { return m[i]; }
    const array<T,Z...>& operator[](int i) const { return m[i]; }

private:
    array<T,Z...> m[A];
};


// generate output by recursion
template<class T, size_t A, size_t... N>
std::ostream& operator<<(std::ostream& s, const array<T,A,N...>& a)
{
    s << "[ ";
    for(size_t i=0; i<A; ++i)
    {
        if(i!=0) s<<", ";
        s << a[i];
    }
    s << "] ";
    return s;
}

//just declare, fill-up and output
int main()
{
    array<int, 3,3,3> a;
    for(size_t i=0; i<3; ++i)
        for(size_t j=0; j<3; ++j)
            for(size_t k=0; k<3; ++k)
                a[i][j][k] = 100 + 100*i + 10 + 10* j + 1 + k;

    std::cout << a << std::endl;
    return 0;   
}

It should output

[ [ [ 111, 112, 113] , [ 121, 122, 123] , [ 131, 132, 133] ] , [ [ 211, 212, 213
] , [ 221, 222, 223] , [ 231, 232, 233] ] , [ [ 311, 312, 313] , [ 321, 322, 323
] , [ 331, 332, 333] ] ]
Emilio Garavaglia
  • 20,229
  • 2
  • 46
  • 63
0

I think i found the answer, and i also managed to make it so that i can use the arrays with any type (int, float, double or even other classes):

template <typename T>
class A1D
{
    T *data;

public:

    int len;

    A1D (int size, T defvalue){
        data = (T*) calloc(size, sizeof(T));

        if (data != NULL){
            len = size;

            for (int i = 0; i<len; i++){
                data[i] = defvalue;
            }
        }
    }

    void print(){

        cout << "[" ;
        for (int i = 0; i<len; i++){
                cout << data[i] << " ";
            }
        cout << "]";
    }

    void del(){
        delete data;
        len = 0;
    }


    T& operator[] (int index){
        if (index >= 0 && index <= len) return data[index];
    }
};

template <typename T>
class A2D
{   
    A1D<T> *data;

public:

    int len;

    A2D (int size_dim1, int size_dim2, T defvalue){
        data = (A1D<T>*) calloc(size_dim1, sizeof(A1D<T>));

        if (data != NULL){
            len = size_dim1;            

            for (int i = 0; i < len; i++){
                data[i] = A1D<T> (size_dim2, defvalue);
            }
        }
    }


    void print(){

        cout << "[";
        for (int i = 0; i < len; i++){
            data[i].print();
        }
        cout << "]";
    }

    void del(){
        for (int i = 0; i < len; i++){
            data[i].del();
        }
        len = 0;
    }


    A1D<T>& operator[] (int index){
        return data[index];
    }
};

template <typename T>
class A3D
{   
    A2D<T> *data;

public:

    int len;

    A3D (int size_dim1, int size_dim2, int size_dim3, T defvalue){
        data = (A2D<T>*) calloc(size_dim1, sizeof(A2D<T>));

        if (data != NULL){
            len = size_dim1;            

            for (int i = 0; i < len; i++){
                data[i] = A2D<T> (size_dim2, size_dim3, defvalue);
            }
        }
    }


    void print(){

        cout << "[";
        for (int i = 0; i < len; i++){
            data[i].print();
        }
        cout << "]";
    }

    void del(){
        for (int i = 0; i < len; i++){
            data[i].del();
        }
        len = 0;
    }


    A2D<T>& operator[] (int index){
        return data[index];
    }
};

//and here is how you use it:

int size1, size2, size3;
cout << "Enter the size of array3d:"; cin >> size1;
cout << "Enter the size of array2d:"; cin >> size2;
cout << "Enter size of array1d:"; cin >> size3;

A3D<int> test(size1, size2, size3, 0);
test.print();

//can also do this:
test[0][0] = A1D<int> (5, 9);
test.print();
7331skillz
  • 141
  • 1
  • 6