-3

I have a class called Actor, and a class called Beast. I want to have an array of all Beast and Actor objects within each Actor and Beast object. So say I have two Actors: a1 and a2, and two Beasts: b1 and b2, there would be an array in a1 that contained a reference to a1, a2, b1, and b2. This same array would be in a2, b1, and b2.

How would I go about making this array?

lolando
  • 1,721
  • 1
  • 18
  • 22
  • 2
    can you post how you tried implementing this already? – Leon Oct 30 '13 at 14:01
  • @ScarletAmaranth: Iinheritance is just one part of the question. The main part is containing references to the objects. – masoud Oct 30 '13 at 14:06
  • I am actually a student and just learning C++, I didn't know what to try. – Afropenguinn Oct 30 '13 at 14:06
  • 1
    Are you insane to store all permutations in each and every object !? –  Oct 30 '13 at 14:07
  • @Dieter Lücking Who says about 'all permutations'? What do you mean by that? Objects can be 'registered' in order they are created, I didn't see any additional requirements related to ordering. Also, array needs to be shared among all instances (because it's the only way to have it synchronized properly, and even makes it easy to get this to work in multi-threaded application), so there will be only one array, containing only one 'permutation', that every object can read at any time. As long as objects are created only in one thread, there is nothing else to concern about. – Mateusz Grzejek Oct 30 '13 at 14:54

3 Answers3

3

You can have two static class members, two vectors and add each instance into this vector in the constructors.

class Animal {
    private:
        static std::vector<Animal*> animal_list;
    public:
        Animal() { animal_list.push_back(this); }
        void print_them() { 
            for (auto iter = animal_list.begin(); 
                    iter != animal_list.end(); 
                    iter++) {
                std::cout << *iter << std::endl;
            }
        }
};

std::vector<Animal*> Animal::animal_list;

int main() {
    Animal a1, b1; 
    a1.print_them();
    return 0;
}

Of course, handling the destructed instances, managing the ownership, and thread safety are some further considerations.

perreal
  • 94,503
  • 21
  • 155
  • 181
  • You forgot about removing object that are being destroyed. Also, your code doesn't show how to store different types (probably related) in single array (this is what question was about). So, in fact, your answer has nothing to do with this problem. – Mateusz Grzejek Oct 30 '13 at 15:13
  • I did not forget removing them, that is left as an exercise. This answer only intends to demonstrate the use of static class members which may have some relation to the OP. – perreal Oct 30 '13 at 15:41
0

There are a couple of conditions here to keep both Actors and Beasts in the same "array". They must both share a common base type, and the array must be an array of pointers.

On top of that, you should probably use a vector instead of an array.

One pattern would be a static vector in the base class, the derived classes could add and remove themselves from the vector when constructed or destroyed:

class Base
{
protected:
    void Add( Base* in )
    {
        m_Vec.push_back(this);
    }
    void Remove( Base* in )
    {
        m_Vec.erase(find(m_Vec.begin(), m_Vec.end(), this));
    }
private:
    static vector<Base*> m_Vec;
};

class Actor : public Base
{
public:
    Actor()
    {
        Add( this );
    }
    ~Actor()
    {
        Remove( this );
    }
};

class Beast : public Base
{
        // do as in Actor
};
Grimm The Opiner
  • 1,778
  • 11
  • 29
0

You have two issues to solve here:

  • First is that from your post it looks like you want to store different types (Actor and Beast) in the same array. You can only do that if both types derive from the same base class, in which case the array needs to be an array of pointers to base class elements. (Side note: based solely on how you named the classes, Beast can potentially derive from Actor, in which case your array could have Actor* elements.)
  • The second problem you might have is type recursion. You want Actors to have references to Beasts, and Beasts to have references to Actors. You cannot fully declare your Actor class without declaring Beast first, but because Beast also references Actor, you cannot declare Beast first either. In C++ you can resolve such recursions by "forward-declaring" classes. Forward declaring a class tells the compiler that the class will be declared at a later point, but for now it should just accept it as a valid class. Between the forward-declaration and the full declaration you will be able to use pointers to the class (and only without dereferencing), but only pointers because the compiler cannot know yet what the class's size or members will be. Forward-declaring both classes is a simple as:

    class Actor; class Beast;

A small note though, if you don't store both classes in separate arrays, but implement the solution in my first point with base classes, then you should also store the common array in the base class, and there is no need to forward-declare Actor and Beast.

ultimA
  • 298
  • 1
  • 9