-4

In a project that I'm working on, I need to make a class that contains an array of pointers to other objects of the same class. I'm currently having trouble initializing this array. Example:

class MrClass{

    MrClass* otherInstances[];

public:

    MrClass(MrClass* x[]){
        otherInstances = x;
    }

}

This array must be arbitrarily sized, since the number of instanced of the class to be passed is defined at compile time and it must be of pointers because multiple instances of the class must have access to the same objects.

supereater14
  • 137
  • 1
  • 1
  • 6

2 Answers2

2

Correct solution

Use std::vector<MrClass *> or std::array<MrClass *>. Or even better, std::vector<std::shared_ptr<MrClass>>

class MrClass{

    std::vector<std::shared_ptr<MrClass>> otherInstances;

public:

    MrClass(std::vector<std::shared_ptr<MrClass>> const & x)
        : otherInstances(x)
    {

    }
}

Auxiliary solution

If you really need an array (and you really know, what you're doing), do the following:

class MrClass{

    MrClass ** otherInstances;
    int otherInstancesCount;

public:

    MrClass(MrClass ** x, int count){

        otherInstances = x;
        otherInstancesCount = count;
    }
}
Spook
  • 25,318
  • 18
  • 90
  • 167
  • It's interesting to note that the semantics of the two solutions are not the same. The code he had seemed to imply a deep copy of the array (but I don't think we can be sure), which `std::vector` does, but not your second solution. – James Kanze Jun 12 '14 at 08:17
  • And what does `shared_ptr` have to do with it? Most of the time, if you have an array of pointers, it is for navigation, and it shouldn't be `shared_ptr`. – James Kanze Jun 12 '14 at 08:18
  • @JamesKanze Yes, the implementations are different. Though, if we assume requirements from the array version, making copy of the original shouldn't be a problem. – Spook Jun 12 '14 at 08:19
  • Well, I'm asking to use an array because later I will be using pointers to elements of it, which doesn't work very well with vectors. – supereater14 Jun 12 '14 at 08:20
  • 1
    What's the problem with a pointer to a `std::vector` element? Or better still, an iterator? – JBentley Jun 12 '14 at 08:22
  • std::vector elements can move around in memory if the vector is changed. For safety, making pointers to them is a bad idea. Also, since this program will eventually be multithreaded, it introduces the possibility of another thread creating pointers to vector elements before the vector is fully constructed. – supereater14 Jun 12 '14 at 08:25
  • 1
    On the first point, how does this differ from an array? In what way can a vector be changed such that a pointer/iterator is invalidated, than an array can't? On the second point, if that is a concern, then what is to stop a thread creating pointers to array elements before they have been constructed? `std::vector` is pretty much designed to be a drop-in replacement for arrays in almost all cases. – JBentley Jun 12 '14 at 08:28
  • @supereater14 "std::vector elements can move around in memory if the vector is changed", yes (if *size* of vector changes as an effect of the operation, otherwise there's no point to reallocate memory for items). But if you keep pointers to instances in the vector, only *pointer's positions* will change. The objects themselves *will still be in the same place*. – Spook Jun 12 '14 at 09:52
  • 1
    @supereater14 Keep in mind, that std::vector internally uses arrays (maybe not literally, but the same rules apply). So if you use array, you'll have exactly the same issues as when using std::vector, except that you'll have to do everything manually instead of using convenient object. – Spook Jun 12 '14 at 09:54
  • 1
    @supereater14 It works as well for `std::vector` as it does for a C style array. Provided, of course, you don't do anything with the vector that you cannot do with the array. – James Kanze Jun 12 '14 at 10:51
0

Arbitrarily sized arrays are written std::vector in C++. So you'd have:

class MrClass
{
    std::vector<MrClass*> otherInstances;
public:
    MrClass( std::vector<MrClass*> const& initialValues )
        : otherInstances( initialValues )
    {
    }
};
James Kanze
  • 150,581
  • 18
  • 184
  • 329