I have a user-defined class Person
and I want to create a variable-sized array (size taken at runtime) of Person pointers.
The following code works as expected.
Person **arr = new Person* [size];
However, I didn't understand exactly whom the *
operator is associated with. I tried putting paranthesis like:
new ((Person*)[size])
new (Person (*)[size])
Only the second option works.
This seems counterintuitive as in a regular static declaration,
Person* arr[10]
would mean an array of Person*
type (Array of Person
pointers) (associativity with Person
).
While Person (*arr)[10]
would mean a pointer to an array of Person
type (associativity with arr
).
Edit: As pointed out by @Jan Schultke
I realised that new Person* [size]
and new (Person (*)[size])
don't have the same effect. One returns Person**
and the other returns Person (**)[size]
.
Also, the second does not allow size to be a variable.
Again, I know I can use vector
for dynamic arrays. I am learning OOP methodology lately, focussing on the concepts of programming language C++, and my aim is to get on grips with what goes on under the hood, rather than simply using a library.
Grammatically, what follows the new
keyword is a
new-type-id, which is a limited form of abstract-declarator.
When you write new Person*
, the principles are the same as if you wrote:
using n = Person*;
// or
void f(Person*);
// or
auto f() -> Person*;
To read abstract-declarators, imagine that there is a variable name in the declaration, like:
Person *p;
Therefore, the *
makes the type a pointer,
and new Person*
is allocating a new pointer.
new Person*[size]
allocates a new array size 10
of pointers (not a pointer to an array) because [size]
has greater precedence in declarators than *
.
new (Person (*)[size])
is allocating a new pointer to a Person[size]
array.
What you're doing here is using the alternative new-expression syntax where you provide a type-id in parentheses, and that works like:
using T = Person(*)[size];
new T;
new ((Person*)[size])
is simply gibberish.
It's as if you wrote a C-style cast in a type, like:
using T = (Person*)[size];
While
Person (*arr)[10]
would mean a pointer to an array ofPerson
type (associativity with arr).
I'm not sure why you're surprised by the behavior.
Person(*arr)[10]
declares a pointer to an array,
and new (Person(*)[10])
allocates a new pointer to an array.
The effect of parentheses is identical in both cases.