Add a list of a class to another class - c++

I'm trying to create a master-slave scenario where the first class contains a list of all the other sub classes. I've created two classes.
If my master class is ControllerDetail and my sub class is ControllerPOD: public ControllerDetail....can I create a list of all ControllerPOD's from the Controller Detail class?
I've tried creating std::list<ControllerPOD> cps; in the private section, but that obviously doesn't work.
Thanks!

Yes, you can:
class ContollerPOD; //forward declaration
class ControllerDetail
{
...
private:
std::list<ControllerPOD> cps;
};
class ControllerPOD: public ControllerDetail
{
...
};

It is slightly ambiguous what you are trying to do here. ControllerDetail is a class not an object, and you will have lots of them, one for each ControllerPOD.
So if you want it to have a list it would have to be static.
Now suppose you want ControllerDetail to have a static list of all the objects currently existing that derive from it. So we will have this:
class ControllerDetail
{
typedef std::list<ControllerDetail * > list_type;
static list_type instances;
list_type::iterator m_iter; // will become apparent later
};
In our constructor of ControllerDetail we will add our instance to the list.
ControllerDetail::ControllerDetail()
{
instances.push_back( this );
m_iter = instances.back(); // iterator that holds our object
}
In our destructor we remove ourselves from the list
ControllerDetail::~ControllerDetail()
{
instances.erase( m_iter );
}
And obviously you may have to handle thread-safety issues in all of this but you can iterate through the list and see all the current instances of the class. As ControllerPOD derives from ControllerDetail, when it is constructed it will get added too.
If you only want specific sub-classes to be added, you can use some kind of flag in the constructor of ControllerDetail as to whether to add itself.
It is generally better for a class to not know the classes that derive from it.
Now if ControllerPOD is not really a type of ControllerDetail then your ControllerDetail would have a list of ControllerPOD* instead, your ControllerPOD constructor would instead add itself and remove itself from the list, and you would have to sort out your "access" to allow it to do so, but the principle is the same.
If your ControllerPOD is passed a "parent" object which is a ControllerDetail, then the parent would have the list as a member and your ControllerPOD would add itself and remove itself from the parent's list. This assumes the parent outlives the child.
If we see what you really want to do, we can look at your class design a bit more clearly.

Related

where to declare the data that needs to be accessible to multiple objects?

I have just started to work with multiple objects/classes and I am having a hard time figuring out how to implement the data structure properly
Assuming I have a base class
class control
{
protected:
char* location
/* node** adjacency_list; This doesn't work */
};
and two different derived classes
class carA:public control
{
};
class carB:public control
{
};
and a node class.
My problem starts when I try to implement a 2D-ish structure like an array of linear linked list (graph) based on location in which the adjacency_list needs to point to the right memory space and must be available to all objects.
If I initialize the adjacency_list pointer to NULL at the base
class constructor, with every derived class object it will be set to
NULL again.
If I create the array in the base class constructor, it will create a
new array for every derived class object.
I tried to find a way with using the copy constructor of the base class in the derived class initialization list, but I couldn't justify/visualize a way that works.
So apart from declaring it globally, what/where is a simple, sensible way to declare this pointer?
I understand this might be extremely trivial, but I just can't see it at the moment.

C++ copy constructor issue with parent/child classes

I've run into a problem with copy constructors...I assume there is a basic answer to this and I'm missing something obvious - maybe I'm doing something entirely wrong - but I haven't been able to figure it out.
Basically, I have a parent class and child class. The parent class contains a vector of pointers to a (different) base class object. The child class wants to instead store pointers to objects derived from that base object.
Here's a pseudocode sample, if that helps:
// Base classes
class ItemRev {
...
}
class Item {
protected:
vector<ItemRev *> m_revPtrVec;
}
Item::Item(const Item &inputItemObj)
{
// Copy contents of the input object's item rev pointer vector
vector<ItemRev *>::const_iterator vecIter = (inputItemObj.m_revPtrVec).begin();
while (vecIter != (inputItemObj.m_revPtrVec).end()) {
(this->m_revPtrVec).push_back(new ItemRev(**vecIter));
}
}
=========
// Derived classes
class JDI_ItemRev : public ItemRev {
...
}
class JDI_Item : public Item {
...
}
JDI_Item::JDI_Item(const JDI_Item &itemObj)
{
// Copy contents of the input object's item rev pointer vector
vector<ItemRev *>::const_iterator vecIter = (inputItemObj.m_revObjPtVec).begin();
// The below does not work!
while (vecIter != (inputItemObj.m_revObjPtVec).end()) {
m_revObjPtVec.push_back(new JDI_ItemRev(**vecIter));
}
}
The problem with the above is in the push_back() call in the JDI_Item copy constructor.
Given this setup, what should the child class's copy constructor look like? Do I even need a child class copy constructor? I assumed I did, because the copy constructor is creating new objects, and the parent copy constructor will create new objects that are not the type I want in the derived class (i.e., the parent object stores pointers to ItemRev objects, while the child object should store pointers to derived JDI_ItemRev objects).
As mentioned in the comments, there is probably a more succinct way to express this problem (i.e. your class structure needs some work).
However, if you want to do it this way, the easiest way to achieve it is to use a virtual clone() method in the base class of ItemRev, with overrides of it defined in derived classes.
e.g.:
class ItemRev {
virtual ItemRev* clone() const = 0;
};
class JDI_ItemRev : public ItemRev {
ItemRev* clone() const override
{
// do your actual cloning here, using the copy constructor
return new ItemRev(*this);
}
};
Now, whenever you call clone() on any class derived from ItemRev, you will be returned an ItemRev* but it will point to a fully constructed derived class. You can of course get to the derived class's interface with static_cast<> or dynamic_cast<>.
...however...
derivation often seems like an easy win but it often turns out not to be. Inheritance should only be used if the derived class really is a type of the base class. Often people select inheritance when the derived class is a lot like a base class, or shares many characteristics with a base class. This is not the time to use inheritance. It's the time to use encapsulation.
In general, inheritance is evil.
On another note, you might find this link interesting.
Presentation on inheritance as an implementation detail

If I have a collection of superclass type, how do I get all the items of a specific subclass type?

I want to create a collection in C++ of type Parent, where I add different subclasses like Child and Child2, and then get all the elements of X subclass. I tried with a vector, but it happens to destroy polymorphism according to this answer. If I use a collection of pointers, I would have to iterate over it sequentially checking the class of every element, is there a better / more efficient solution?
Here's an example code:
class Parent
{
public:
int id;
Parent(){ id = 8; }
};
class Child: public Parent
{
int foo;
public:
Child(int n){ foo= n; }
};
class Child2: public Parent
{
int bar;
public:
Child2(int n){ bar= n; }
};
Pseudocode:
GenericCollection<Parent> collection; //Full of elements Child and Child2.
This is the method I want to implement:
collection.getElements<Child2>();
Thanks for everything.
You cannot do this with objects because of the object slicing problem. You need to use pointers instead - preferably, smart pointers, such as unique_ptr<Parent>:
GenericCollection<unique_ptr<Parent>> collection;
Now you can implement your getElements method that uses Run-Time Type Information (RTTI) to detect the type of the object pointed to by the smart pointer, and keep only the ones pointing to Child2.
Note that in order to use RTTI your base class Parent needs to have at least one virtual member function. This shouldn't be an issue in your case, because you expect polymorphic behavior.
In C++ you can't directly do what you're asking, because items are stored "by value" in the vector, so you'll only end up with the parent portion of each object while the child-specific parts will be sliced away.
However we may be able to solve your real problem.
If you really need to be able to generate separate lists of child1 and child2 objects, the C++ idiom would be separate vectors to contain each different type.
If however all you need is polymorphism, then you could have a vector of (smart) pointers to the base class, and operate on those polymorphically. If you take this approach don't try to get a list of a specific child's objects but instead utilize an appropriate abstract interface to perform your logic.
In this case you can't. Read about object slicing for more information.
It will only work if you have a collection of pointers. For this I recommend you read about std::unique_ptr.

Scene graph child node registration & copy constructor

I have a scene graph, all nodes deriving from a base class AbstractNode. AbstractNode has a registerChild member function:
registerChild<T>(string name, shared_ptr<AbstractNode> * childMember)
used for registering the children in a standard way (so that they can be listed and modified in the base class interface). It basically adds the name/child_pointer pair to a hash.
So for instance the class material will be declared like that (shortened):
class Material : public AbstractNode
{
public:
Material() { registerChild(&color); }
private:
std_shared<Color> color;
}
Color being another subclass of AbstractNode.
Now I would like to implement a copy constructor for AbstractNode. It must copy the list of registered children, and update the child member pointers. I would like to avoid reimplementing the copy constructor in all base classes. Is this possible?
I have thought of working on pointer offsets, between this and the child pointers. But are these guaranteed to be constant between two instances? It seems like a big hack to me... (And I'm even sure that this is not guaranteed when subclassing)
Thanks,
Etienne

Auto detaching objects?

I have a mother class that stores the pointers to some objects in a list. I want these objects to detach themselves from the list when they are destroyed.
Can anyone suggest some good ways to do this please?
The crude way is to store the container reference (or pointer) in the objects in the list and remove themselves in their destructors:
class Contained;
class Container {
std::list<Contained*> children;
public:
...
void goodbye(Contained*);
};
class Contained {
Container& c; // you set this in the constructor
public:
~Contained() { c.goodbye(this); }
};
Note that this makes the Contained class non-copyable.
The easy way is to use some framework that already provides such functionality. Eg. if you use Qt, you would just derive the Contained class from QObject and store QPointer<Contained> in the Container. The QPointer would be set to zero once the contained object is deleted.
Or, if you use some memory management facilities like boost::shared_pointer, (I assume the Container doesn't own the Contained objects, otherwise, it knows best when the child object dies), you would use a weak pointer in the Container, which has similar functionality.
you can add reference/pointer to the mother class in those classes and when destructor is called they call mother.Detach(this)