28

In C++ if I want an array of pointers so that I may have them point to different objects at a latter stage what does the syntax look like.

EDIT

I need to clarify what I am trying to do I guess. I have a class foo that has and add method. In the add method I take a reference to class bar. I want to save that reference into a pointer array of bar. The array of pointer bar will need to be expanded all the time this I have no problems with. It is creating and array on the heap of pointers so that I may assign bar objects to them later. What I have tried seems to fail as class bar does not have a default constructor which the compiler is complaining about. This lead me to think that I was creating and array of actual objects which I did not want to do.

Please no stl and no I do not want to hear about how you think this is crazy etc that is your opinion.

Evan Carslake
  • 2,267
  • 15
  • 38
  • 56
Thomas
  • 2,939
  • 6
  • 32
  • 29
  • 1
    This doesn't strictly answer your question, but in most cases it would be better to use an array of pointers. e.g. std::vector collection; – Conspicuous Compiler May 21 '10 at 05:08
  • what is meant by "no actual initialization of foo objects" ? Also, do you know how many elements in the array at compile time itself? – Naveen May 21 '10 at 05:20
  • What code have you produced so far? – default May 21 '10 at 06:38
  • 3
    “no stl and no I do not want to hear about how you think this is crazy etc that is your opinion” – you *do* realize how ignorant and condescending at the same time that sounds? You may have good reasons to shun the STL – but why not tell us them to cut all this short? – Konrad Rudolph May 21 '10 at 08:41

5 Answers5

64

What you want is:

Foo *array[10]; // array of 10 Foo pointers

Not to be confused with:

Foo (*array)[10]; // pointer to array of 10 Foos

In either case, nothing will be automatically initialized because these represent pointers to Foos that have yet to be assigned to something (e.g. with new).

I finally "got" pointer/array declaration syntax in C when I realized that it describes how you access the base type. Foo *array[5][10]; means that *array[0..4][0..9] (subscript on an array of 5 items, then subscript on an array of 10 items, then dereference as a pointer) will access a Foo object (note that [] has higher precedence than *).

This seems backwards. You would think that int array[5][10]; (a.k.a. int (array[5])[10];) is an array of 10 int array[5]. Suppose this were the case. Then you would access the last element of the array by saying array[9][4]. Doesn't that look backwards too? Because a C array declaration is a pattern indicating how to get to the base type (rather than a composition of array expressions like one might expect), array declarations and code using arrays don't have to be flipflopped.

Joey Adams
  • 41,996
  • 18
  • 86
  • 115
  • +1 Yes, C declarations actually do make sense once you understand them :) – fredoverflow May 21 '10 at 06:18
  • 10
    For future visitors to this question: You can use a [tool like this](http://cdecl.org/) that translates these declarations into something that resembles English, to get a better understanding of how a variable is declared. – Sumurai8 Nov 19 '13 at 15:42
10

For example, if you want an array of int pointers it will be int* a[10]. It means that variable a is a collection of 10 int* s.

EDIT

I guess this is what you want to do:

class Bar
{
};

class Foo
{
public:

    //Takes number of bar elements in the pointer array
    Foo(int size_in);

    ~Foo();
    void add(Bar& bar);
private:

    //Pointer to bar array
    Bar** m_pBarArr;

    //Current fee bar index
    int m_index;
};

Foo::Foo(int size_in) : m_index(0)
{
    //Allocate memory for the array of bar pointers
    m_pBarArr = new Bar*[size_in];
}

Foo::~Foo()
{
    //Notice delete[] and not delete
    delete[] m_pBarArr;
    m_pBarArr = NULL;
}

void Foo::add(Bar &bar)
{
    //Store the pointer into the array. 
    //This is dangerous, you are assuming that bar object
    //is valid even when you try to use it
    m_pBarArr[m_index++] = &bar;
}
Naveen
  • 74,600
  • 47
  • 176
  • 233
  • Don't forget to implement (or declare as private) a copy operator, see [Rule Of Three](http://stackoverflow.com/q/4172722). – basic6 Nov 12 '14 at 15:36
4

I would do it something along these lines:

class Foo{
...
};

int main(){
  Foo* arrayOfFoo[100]; //[1]

  arrayOfFoo[0] = new Foo; //[2]
}

[1] This makes an array of 100 pointers to Foo-objects. But no Foo-objects are actually created.

[2] This is one possible way to instantiate an object, and at the same time save a pointer to this object in the first position of your array.

triktae
  • 123
  • 4
3

If you don't use the STL, then the code looks a lot bit like C.

#include <cstdlib>
#include <new>

template< class T >
void append_to_array( T *&arr, size_t &n, T const &obj ) {
    T *tmp = static_cast<T*>( std::realloc( arr, sizeof(T) * (n+1) ) );
    if ( tmp == NULL ) throw std::bad_alloc( __FUNCTION__ );
       // assign things now that there is no exception
    arr = tmp;
    new( &arr[ n ] ) T( obj ); // placement new
    ++ n;
}

T can be any POD type, including pointers.

Note that arr must be allocated by malloc, not new[].

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
2

boost:ptr_array

http://www.boost.org/doc/libs/1_43_0/libs/ptr_container/doc/ptr_array.html

ronag
  • 49,529
  • 25
  • 126
  • 221