Search code examples
c++arraysclass

Base Operand of -> has non-pointer type error when creating an array of classes


I would like to learn why the base operand -> works in some cases and not in others when used with a pointer.

I realize I need to use a . instead of a -> when I receive this error. I'm trying to understand why a . is needed when I reference my pointer as an array element as p[i].somefunct(), and -> is required when I reference my pointer directly as (p+i)->somefunct().

I wrote a sample program to illustrate both methods, and wonder if any more experienced voices can explain this C++ behavior.

I'm also interested in learning if there is a better way to create, access, and destroy an array of pointers to a class that is stored on the heap.

#include <iostream>
using namespace std;

class KClass {
public:
    int x;
    KClass(){};
    ~KClass(){};
    int getx(){ return x; }
    void setx(int data){ x = data; return; }
};

int main()
{
    //use the heap to create an array of classes
    KClass *pk = new KClass[3]; //array of 3 pointers
    KClass *pk1 = new KClass[3]; //array of 3 pointers
    //do something
    for (int i = 0; i < 3; i++){
        (pk+i)->setx(i);
        cout << "(pk+" << i << ")->getx(): " << (pk+i)->getx() << endl;
    }
    cout << endl;
    for (int i=0;i<3;i++){
        //does not compile: pk1[i]->setx(i);
        //why is different syntax required when I access pk1 as an element of an array?
        pk1[i].setx(i);
        cout << "pk1[" << i << "].getx(): " << pk1[i].getx() << endl;
    }
    delete [] pk;
    delete [] pk1;
    pk = nullptr;
    pk1 = nullptr;

    getchar();
    return 0;
}

Solution

  • The difference is very simple. p[i] is exactly the same as *(p + i). Absolutely the same, to the point of i[p] being a valid (albeit super confusing) form of writing array subscription.

    Because of that, when you use p[i] form, you already dereference the result, so you access members via . member access.

    If you are using (p + i) without dereferencing, you need to access members via -> access operator, since you are dealing with pointer.

    Just a rehash - -> is no more than convenience shortcut. Whenever you write something like a->x you can always write it as (*a).x