Johnny
Johnny

Reputation: 83

`Array[i]` vs `Array+i`

#include <iostream>
#include <string>

using namespace std;

class Plane
{
    private:
        // data member
        string name;

    public:
        // constructor
        Plane();

        // destructor
        ~Plane();

        // member function
        void setName(string na);
};

int main()
{
    int num_plane;

    cout << "How many planes do you have? ";
    cin >> num_plane;

    Plane *p_to_plane = new Plane[num_plane];

    string name;
    for (int i = 0; i < num_plane; ++i)
    {
        cout << "The No. " << (i + 1) << " plane's name: ";
        cin >> name;

        (p_to_plane + i)->setName(name);
    }


    delete [] p_to_plane;

    system("Pause");

    return 0;
}

I have a question:

In main function, there is a for loop to add names to every plane. However, if I write p_to_plane[i]->setName(name), then an error happens. The compiler asks me to write p_to_plane[i].setName(name).

I cannot understand why. If it is p_to_plane[i].setName(name), then p_to_plane[i] should be a class object. However, should it not be the pointer which points to the class object?

Additionally, I can't tell the difference between p_to_plane[i] and p_to_plane + i. Are they the same?

Upvotes: 0

Views: 91

Answers (2)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385144

p_to_plane is a Plane* (a pointer).

*p_to_plane dereferences that pointer, giving you a Plane (the first in the array).

p_to_plane+i increments that pointer, giving you an adjusted pointer to elsewhere in the array.

*(p_to_plane+i) deferences the adjusted pointer, giving you a Plane (the ith in the array).

p_to_plane[i] is the same as *(p_to_plane+i).

So, the compiler is right: [] has already done the dereference for you.

Upvotes: 1

melpomene
melpomene

Reputation: 85767

a[b] means *(a + b). It's a dereference operation.

Similarly, a->b means (*a).b.

If p is a pointer to the first element of an array of objects, then you can access their methods using either of

  1. (*(p + i)).foo()
  2. (p + i)->foo()
  3. p[i].foo()

In variant #2, the -> operator is doing the dereferencing; in variant #3, the [] operator is doing the dereferencing.

(If you really want to combine them, you need something like (&p[i])->foo(), but that's just silly.)

Upvotes: 4

Related Questions