tags:

views:

111

answers:

3

I have a structure usually containing a pointer to an int. However, in some special cases, it is necessary that this int pointer points to another pointer which then points to an int. Wow: I mentioned the word pointer 5 times so far!

  • Is this even possible?

I thought about it that way: Instead of using a second int pointer, which is most likely not possible as my main int pointer can only point to an int and not to another int pointer, I could make it a reference like this:

int intA = 1;
int intB = 2;
int& intC = intB;

int* myPointers[ 123 ];
myPointers[ 0 ] = &intA;
myPointers[ 1 ] = &intB;
myPointers[ 3 ] = &intC;

So the above would do what I want: The reference to intB (intC) behaves quite like I want it to (If it gets changed it also changes intB)

  • The problem: I can't change references once they are set, right? Or is there a way?

Everything in short: How do I get a value to work with * (pointers) and ** (pointers to pointers)?

A: 

You could put a pointer to intB in both array elements:

myPointers[ 1 ] = &intB;
myPointers[ 3 ] = &intB;

This way both elements point to the same variable and *myPointers[1] will always be the same as *myPointers[3]. Is this what you want to achieve?

sth
Not really: I need a variable which is "compatible" to the type int* but points to an element of myPointers. Basically: A value stored in myPointers, which can *change* its target, and does itself point to a variable in myPointers again.
Ptr
+2  A: 

int* and int** are different types so you can't use one as the other without using a potentially non-portable cast.

In the declaration:

int& intC = intB;

The reference intC will always refer to the int intB. The binding cannot be changed.

You could use a union to support a type that could be either an int* or an int** but you would need to be certain when you're reading, which member of the union is valid at any point.

union PIntOrPPInt
{
    int* pint;
    int** ppint;
};

int intA;
int intB;
int* pintC = &intB;

PIntOrPPInt myPointers[ 123 ];

myPointers[ 0 ].pint = &intA;
myPointers[ 1 ].pint = &intB;
myPointers[ 3 ].ppint = &pintC;
Charles Bailey
And there is no different approach? I would have to rewrite everything then..
Ptr
What sort of approach do you mean? If you want to store something that could be one of two types then you need a type than can support this. A `union` is probably the simplest such type.
Charles Bailey
@Ptr: I suppose you could have an array of `void*` and use a `reinterpret_cast` to convert to the correct type as needed. I don't see this having any advantages over the `union` solution, though.
Charles Bailey
A: 

We rarely if ever use pointers to pointers in C++. Instead, like you suggest, we use reference to pointers. That said, C++ is a strongly-typed, static-typed language. So you have to decide at compile-time what your array elements are going to point to.

One approach is to wrap the array elements in a class:

struct P {
    P() : p(0) { }
    P(int* p) : p(p) { }
    P(int** p) : p(*p) { }
    operator int*() const { return p; }
    int *p;
};

int main(int argc, char* argv[])
{
    int *i1 = new int(5);
    int **i2 = &i1;
    int *&i3 = i1;
    P arr[4] = {i1, i2, i3, P()};
    delete i1;
    return 0;
}
wilhelmtell