Re: Question about arrays in objects

From: Leor Zolman (leor_at_bdsoft.com)
Date: 01/17/04


Date: Sat, 17 Jan 2004 02:47:27 GMT

On Sat, 17 Jan 2004 01:52:28 GMT, Joec <joec@annuna.com> wrote:

>I want to create a 2d array as an object member.
>
>like:
>
>class x{
>private:
>const int num;
>int array[num];
>...
>
>do I have to use a pointer like:
>int *px;
>
>then put the array in the constructor and use the pointer?

A couple of things need clarification here:

1. You said "2d" array, but you show a definition for a 1d array (and
have only a single dimension value, "num"). Do you really want a
1-dimensional, or a 2-dimensional array?

2. Do you intend for the dimension(s) of your array (be it 1d or 2d)
to be "compile time constant", or do you want the dimension(s) to be
supplied at run time at the time the object containing this array is
to be instantiated? That will drive your implementation technique.

Just to keep the examples simple, let's use a 1d array (although the
pointer-based solution I'll discuss below gets more complicated with
multiple dimensions). If the dimension is to be a compile-time
constant (not what I think you're looking for, but I'm just trying to
cover all the bases), then the best way to define it is as an
enumeration constant:

        class x {
                enum {num = 100};
                int array[num];
        };

There's at least one other way to do this, using a static const int
(or size_t, rather, if you want to be a stickler about it), but I
think the enum way is the cleanest.

Now, if you want the size of the array to be specified at run-time and
handled in the constructor, you just can't use a plain old array. A
std::vector would be a good choice, because it'll handle its own
memory management for you, and you wouldn't need any asterisks in your
program (well, at least not for this).

If you'd prefer to "roll your own" dynamic array implementation, then
that is where using a pointer would come in. Note that you can't use a
built-in array, because array dimensions must be compile-time
constants. A class data member defined as
        const int num;
the way you wrote it above wouldn't work because the compiler can't
predict its value at compile time. num would have to be set in the
constructor using a member initializer, e.g.,
        x::x(int size) : num(size) { ... }
and thus it would not count as a "compile time constant".

 In your class, you'll need at least a pointer to int. Most folks
would also store the dimension in the object, in order to permit
bounds checking or size querying. The class definition would then have
at least this:

        class x {
        public:
                x(size_t size); // constructor
                ~x(); // destructor
                // other member functions...
        private:
                size_t n_elements;
                int *datap;
        };

and the job of the constructor would be to set n_elements to the value
of the "size" parameter, and to allocate memory for holding that many
ints and save a pointer to that memory in datap. Many folks prefer to
do all that in the initializer list of the constructor, because there
are often performance benefits in C++ to doing as much as you can in
the initializer list rather than in the body of the constructor
(though it wouldn't matter much in this case):

        x(size_t size) : n_elements(size),
                        datap(new int[size])
        {}

That should get you started... oh yeah, what about if you really
wanted two dimensions? Unfortunately, this isn't as easy to generalize
as the compile-time constant-sized array code would be. You might
choose to just allocate a 1-dimentional array (sized by multiplying
the x and y dimensions provided to the constructor). Another approach
might be to define a 1d dynamic array of pointers to int (using a
single pointer as above, but declared as int ** instead of just int
*), and then allocate each int * in the array individually. This is a
pain to set up, but accessing elements might go faster by allowing you
to avoid multiplications to locate individual elements. Fun, fun.
HTH,
        -leor

        

Leor Zolman
BD Software
leor@bdsoft.com
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
           Decryptor at www.bdsoft.com/tools/stlfilt.html



Relevant Pages

  • Re: Sorting records using sort()
    ... > We have an array of n*m bytes. ... > proxy objects store a pointer to some master descriptor that stores the ... > need a default constructor, the value type needs to be assignable only ...
    (comp.lang.cpp)
  • Re: Warning on assigning a function-returning-a-pointer-to-arrays
    ... This declares pfunc as a function taking no arguments and returning ... int x, y; ... Presumably pfuncwill return a pointer to a single int, ... or the first of a sequence of "array 5 of int"s. ...
    (comp.lang.c)
  • Re: Newbie
    ... to talk about the int value 3 and the int value 4, ... It also lets you talk about pointer ... C has a special rule for array objects. ... to printf() is: ...
    (comp.lang.c)
  • Re: union {unsigned char u[10]; ...}
    ... But character type is not a union. ... u.a is of type int. ... has to do so to make pointer equality work consistently). ... were a single-element array. ...
    (comp.lang.c)
  • Re: union {unsigned char u[10]; ...}
    ... But character type is not a union. ... u.a is of type int. ... has to do so to make pointer equality work consistently). ... were a single-element array. ...
    (comp.lang.c)