[LC++]couple of questions (was: Re: testing)
Carlo Wood
carlo at alinoe.com
Wed Oct 31 12:28:49 UTC 2001
On Wed, Oct 31, 2001 at 10:57:56AM +1030, Mark Phillips wrote:
> Okay, I think I know where I went wrong. My understanding is that with
> an array, "int myArray[30];" for example, then "myArray" refers both
> to the entire array and to a pointer to myArray[0].
The syntax of [] is slightly confusing I suppose because it doesn't
follow the normal
TYPE name;
declaration form.
However, [] is part of the type - the size inclusief. So lets
think of the TYPE involved here as "int [30]". That means
30 *contigious* objects of the builtin-type 'int'. In other
words, it is a memory block with the size: 30 * sizeof(int) ==
120 bytes (assuming sizeof(int) == 4).
The TYPE being "int [30]", you could think of the declaration to be:
int[30] myArray;
You will find that sizeof(myArray) is indeed 120!
However, it is allowed to do:
int* p = myArray;
After which p will point to the first int of myArray.
Of course, sizeof(p) will be 4 now (assuming sizeof(void*) == 4).
Moreover, this conversion is implicit, you can do:
int i = *myArray;
and the compiler will apply the unary operator* on an 'int*' (myArray
was first converted to an int*).
The same holds for objects:
class Foo;
Foo a[30];
will be a contigious memory block of 30 Foo objects. sizeof(a) == 30 * sizeof(Foo).
And you can do: Foo* p = a;
Because Foo is a class instead of a builtin type, the compiler will
take care that for each of the 30 objects the constructor is called.
Consider this program:
#include <iostream>
class Foo {
private:
int i;
int j;
public:
Foo(void) { std::cout << "Calling constructor of Foo with this == " << (void*)this << '\n'; }
};
Foo a[4];
int main(void)
{
return 0;
}
This outputs:
~>a.out
Calling constructor of Foo with this == 0x804f580
Calling constructor of Foo with this == 0x804f588
Calling constructor of Foo with this == 0x804f590
Calling constructor of Foo with this == 0x804f598
As you see, the `this' pointer is every time sizeof(Foo) larger.
However, inside the class, `this' has type 'Foo*' and points to
THIS (the current) object -- there is no way you can know if
that Foo is part of an array, and if so, which element of that
array it would be. Using this[1] would be Very Bad Coding(tm)
because it would access something outside the current object.
> So there is a
> degree of ambiguity. Now an object can be made to look like an array,
> using "operator[]". My thought was that perhaps this same type of
> ambiguity was available for objects made to look like an array.
Using operator[] for pointers is defined to allow the following:
Foo a[30]; // Define a to be of type Foo[30].
Foo* p = a; // Convert a to type Foo*, pointing to the first element.
Foo f = p[10]; // Get the eleventh element.
This can only be done when the objects of an array are *contigious*
in memory: the elements of an array would be scattered all over memory
then the above would be hard to implement for arbitrary types.
The way the last line works as follows: p[10] means *(p + 10)
Note that operator+ on pointers advances the pointer with a whole
object at a time: If p == 0x804f580, then p + 1 == 0x804f588.
Now what you are refering to is something completely different.
The above is the builtin (pre-defined) definition of what operator[]
means for pointer types (a TYPE*). But if you want a class to "look
like an array" then what you do is explicitely defining an operator[]
for a *class* (which is not a pointer!). For example:
class Bar {
Foo __array[30];
public:
Foo& operator[](int i) { return __array[i]; } // define operator[] for a class
};
This allows one to do
Bar b;
Foo f = b[10]; // Calls b.operator[](10)
> But
> where I am probably getting confused is that myArray is a pointer
> to "int", not a pointer to "myArray[30]", which is the equivalent of
> what "this"
> points to.
I don't think this line made sense, which is why I wrote the above.
Hope it made things more clear for you.
--
Carlo Wood <carlo at alinoe.com>
More information about the tuxCPProgramming
mailing list