3

(C++) Hi, i have problem with declaring object, lets take a look of it first:

class arr1D
{
protected:
    int size;
    int *arr;
public:
    arr1D( int a[] ):size(sizeof(a)/sizeof(a[0])), arr(new int[size])
    {
        for(int i = 0; i < size; i++)
        {
            arr[i] = a[i];
        }
    }
    arr1D( int siz = 10 ):size(siz), arr(new int[size])
    {
        for( int i = 0; i < size; i++)
        {
            arr[i] = 0;
        }
    }
    friend ostream & operator<<( ostream &,const arr1D &);
};
int main()
{
    //arr1D *a1 = new arr1D;
    //cout << *a1;
    //prints "arr: 0 0 0 0 0 0 0 0 0 0 size: 10"
    return 0;
}
ostream & operator<<( ostream &_return, const arr1D &a)
{
    _return << "arr: ";
    for(int i=0;i<a.size;i++)
    {
        cout << *(a.arr+i) << " ";
    }
    _return << "size: " << a.size;
    return _return;
}

I want to declare an object which contains an array of integers something like this:

arr1D a1[] = {1,2,3,4,5}; // pseudo-code

This should print something like this:

arr: 1 2 3 4 5 size: 5

Thanks for help!

JeJo
  • 30,635
  • 6
  • 49
  • 88
  • Possible duplicate of https://stackoverflow.com/questions/9443957/using-sizeof-on-arrays-passed-as-parameters – Galik Jun 07 '18 at 18:58
  • `arr1D( int a[] )` will not work, `a` is a pointer in this context and lost size, see how `std::vector` does it or even use `std::vector` instead – Slava Jun 07 '18 at 18:58
  • I've never used vector yet, right now i'm trying to solve it in that way. Any ideas? – justanordinaryguy Jun 07 '18 at 19:00
  • unrelated, Where is the distructor? – JeJo Jun 07 '18 at 19:01
  • https://stackoverflow.com/questions/4118025/brace-enclosed-initializer-list-constructor – Abdul Ahad Jun 07 '18 at 19:17
  • Be **very** careful here; the constructors correctly initialize the two data members, but that's because of the **order of the declarations** of the data members, and **not** because of the order of the initializers in the constructors. Data members are initialized in the order of their declarations. If you swapped `int size;` and `int *arr;` the initialization would fail, because `arr` would be initialized before `size` was initialized. – Pete Becker Jun 07 '18 at 20:16
  • 2
    "I've never used vector yet" it's never too early to start using `vector`. Just forget that `[]` arrays exist. Also you don't need `new` to create objects. `std::vector a1 = { 1, 2, 3, 4, 5 };` is all you need – Caleth Jun 07 '18 at 21:11

1 Answers1

3

I want to declare an object which contains an array of integers something like this: (pseudocode) "arr1D a1[] = {1,2,3,4,5};" This should print something like this: "arr: 1 2 3 4 5 size: 5" Thanks for help!

You can use it by having initializer list constructor in your class.

Something like as follows:

#include <iostream>
#include <initializer_list>

class arr1D
{
protected:
    int size;
    int *arr;
public:
    arr1D(std::initializer_list<int> input) : size(input.size())
    {
        int* temp = new int[size];
        int index = 0;
        for (const auto& it : input)
        {
            temp[index] = it;
            ++index;
        }
        arr = temp;
    }
        // reaming code...

See Live HERE

Note that, you also need a distrctor in arr1D class otherwise there will be a memory leak as you have pointer member in your class.


As an alternative, use the smart pointers, which is the smart way of handling the dynamic memory, what you allocate in heap.

See a sample solution HERE

#include <iostream>
#include <initializer_list>
#include <memory>

class arr1D
{
protected:
    int size;
    std::unique_ptr<int[]> arr;
public:
    arr1D(std::initializer_list<int> input) : size(input.size())
    {
        arr = std::unique_ptr<int[]>(new int[size]);
        int index = 0;
        for (const auto& it : input)
        {
            arr[index] = it;
            ++index;
        }
    }
    .......
    .......
std::ostream & operator<<(std::ostream &_return, const arr1D &a)
{
    _return << "arr: ";
    for (int i = 0; i< a.size; i++)  std::cout << a.arr[i] << " ";

    _return << "size: " << a.size;
    return _return;
}

PS:However, this is more suitable to handle with std::vector<>. If you do not know how that works, see this question.

Edit: As @M.M mentioned about passing std::initializer_list by value is suitable rather than by reference, edited the constructor of the class.

JeJo
  • 30,635
  • 6
  • 49
  • 88
  • 1
    `std::initializer_list` is supposed to be passed by value . [see here](https://stackoverflow.com/questions/17803475/why-is-stdinitializer-list-often-passed-by-value) – M.M Jun 07 '18 at 21:10
  • @M.M Thanks for this answer. thats something interesting to me. `const&` is my habit actually, but its not suitable everywhere. I will edit it. – JeJo Jun 07 '18 at 21:13