-1

I have an array of size MAX of class pointers.

How can I define a pointer to the same, and access member functions of base, derived, etc?

class base
{
public :
    base() {cout << "base class constructor" << endl;}
    virtual void g() {cout << "base :: g()" << endl;}
};

class derived_1 : public base
{
public :
    derived_1() : base() {cout << "derived_1 class constructor" << endl;}
    virtual void g() {cout << "derived_1 :: g()" << endl;}
};

class derived_2 : public derived_1
{
public :
    derived_2() : derived_1() { cout << "derived_2 class constructor" << endl;}
    void g(int) {cout << "derived_2 :: g()" << endl;}
};

int main()
{
    int i;
    base b;
    derived_1 d_1;
    derived_2 d_2;

    base* arr[MAX] = {&b, &d_1, &d_2};
    base *(*pArr)[MAX];

    pArr = arr;

    for (i=0 ; i < MAX ; i++)
    {
        pArr[i]->g();
    }

    return 0;
}

I get a compilation error:

error: cannot convert 'base* [3]' to 'base* (*)[3]' in assignment

When I change it to below, it works, however it looks more like a hack to me, and method 1 looks more formal to me:

base* arr[3] = {&b, &d_1, &d_2};
base **pArr;

pArr = arr;

for (i=0 ; i < 3 ; i++)
{
    pArr[i]->g();
}
9
  • 1
    Please post a minimal reproducible example Commented Feb 16, 2023 at 16:09
  • arr is a pointer of MAX pointers to base. pArr is a pointer to such array, you cannot simply assign one to the other. & is the address of operator. Commented Feb 16, 2023 at 16:11
  • 2
    it doesnt work for the same reason int x = 42; int * p = x; wont compile Commented Feb 16, 2023 at 16:11
  • 1
    though it is unclear why you think you would need pArr Commented Feb 16, 2023 at 16:12
  • pArr[i]->g(); is totally wrong. You want arr[i]->g() Commented Feb 16, 2023 at 16:13

2 Answers 2

1

Apparently you want the address of the array, not the array itself, when assigning it to a pointer to an array type:

constexpr auto length = 1;
base* arr[length] = {&b};
base* (* pArr)[length] = &arr;
Sign up to request clarification or add additional context in comments.

Comments

1

In the first code snippet you declared a pointer of the type base * ( * )[MAX]

base *(*pArr)[MAX];

However you are trying to initialize it with a pointer of the type base **

pArr = arr;

due to implicit conversion of the array designator arr to pointer to its first element. However there is no implicit conversion between the pointer types base ** and base * ( * )[MAX].

Instead you need to write

pArr = &arr;

for (i=0 ; i < MAX ; i++)
{
    ( *pArr )[i]->g();
}

In this subexpression ( *pArr )[i] at first the pointer pArr is dereferenced ( *pArr) and yields an lvalue reference to the original array arr that is used in the subscript operator ( *pArr )[i] is implicitly converted to pointer to its first element.

In the second code snippet code snippet the pointer pArr is declared as having the pointer type base ** and the initializing expression (due to the implicit conversion mentioned above) also has the same type base **. So the second code snippet is valid.

From the C++17 Standard (7.2 Array-to-pointer conversion)

1 An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The temporary materialization conversion (7.4) is applied. The result is a pointer to the first element of the array.

The difference between the first code snippets and the second code snippet is that in the second code snippet you need not to dereference the pointer pArr to get a pointer to the first element of the array of the type base **.

Pay attention to that in this declaration

base* arr[MAX] = {&b, &d_1, &d_2};

the identifier MAX must be equal exactly to 3. Otherwise in this for loop

for (i=0 ; i < MAX ; i++)

null pointers can be dereferenced that results in undefined behavior. Or if the value of MAX is greater than 3 then you should write the for loop like

for (i=0 ; i < MAX && ( *pArr )[i] != nullptr; i++)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.