Dynamic instantiation in C++ - c++

I want my code to be extensible, in a way where at runtime I create the objects.
For example, let's say I have a Grocery class which has an array of fruits and I want to fill this array of fruits with objects which derives from fruits.
class Fruit{
};
class Grocery{
std::vector<Fruit*> m_fruits;
};
class Apple: Fruit{
};
class Pineapple: Fruit{
};
Now at runtime I want my Grocery class vector m_fruits to be filled with class objects of Apple and Pineapple. So is it possible in some way.
if I add another fruit as strawberry in future, its object will be created and added to the vector of Grocery dynamically without changing the implementation of Grocery class?
Code help will be appreciated.

Check your textbook. It probably mentions that you can only treat pointers to types polymorphically. In other words, a vector of pointers to fruit can take pointers to apples or pineapples.

Well, if you want to make it so your Grocery class can generate any type of fruit. Even fruit that has been implemented after the grocery class has been locked away, I suppose you might be after something like the following?
typedef Fruit*(*FruitInstantiatorPtr)();
template<class T>
Fruit* FruitInstantiator()
{
return new T();
}
// Then in Grocery have a function like:
static void AddFruitGenerator(FruitInstantiatorPtr instantiatorFunc, string fruitTypeName);
////
//Then someone somewhere can go:
class MyNewFruit:Fruit{};
MyGrocery.AddFruitGenerator(FruitInstantiator<MyNewFruit>, "myAwesomeNewFruit");
And that way your Grocery class will be able to instantiate any type of fruit added in the future.

Assum that Fruit has pure virtual functions (denoted by virtual func() = 0) you would need to store pointers to Fruit objects inside your vector std::vector<Fruit*>.
Unfortunately standard containers aren't particulary good at handling pointers and you will have to delete all objects inside your vector in the destructor of your Grocery. You might consider shared_ptr from TR1 or the boost library.
A word on naming: Instantiation isn't the proper word in this case.

You cannot store objects of a derived type by value in any container of a base type without object slicing occuring.
You need to do one of the following:
Use a vector of raw pointers to the base type, e.g. std::vector<Fruit*> and manage the lifetime of the individual Fruit instances yourself (this is the least desirable option).
Use a vector of smart pointers to the base type, e.g. std::vector<boost::shared_ptr<Fruit> >, and allow reference counting to manage the individual items' lifetimes.
Use boost::ptr_vector<Fruit> to store the items, and the items' lifetime are bound to that of the containing ptr_vector.
Depending on your need, #2 & #3 are preferable. #1 should be avoided, as it involves manual effort to manage the lifetimes and could easily result in memory leaks if done incorrectly.

Related

Iterate over different objects

I would like to iterate over different objects that all inhereit from the same superclass. That means I have a superclass like this:
class fruit
{
public:
fruit()
{
}
};
And I have subclasses like this, which define the objects that are used in my code:
class apple: public fruit
{
public:
apple()
{
}
};
class banana: public fruit
{
public:
banana()
{
}
};
Now I want to iterate over all fruits (apples, bananas):
for ( first fuit; last fruit; next fruit )
{
// do something, no matter if apple or banana
}
But how should I do this since apples and bananas are different class types, but they share the same superclass. This is why I think, that there has to be an elegant way to do it.
C++ doesn't have any kind of built-in object registry where you can get access to every existing object of a particular type. However, C++ has multiple container types that can be used to store multiple objects in a variety of different data structures.
Since the objects you are storing are of different types but with a common base type, you need to use pointers or references to achieve polymorphic behavior and avoid object slicing.
For example, you can use a vector of std::unique_ptr objects.
std::vector<std::unique_ptr<fruit>> fruits;
fruits.emplace_back(new apple);
fruits.emplace_back(new banana);
for (auto &fruit : fruits) {
// fruit is a reference to the unique_ptr holding the pointer-to-fruit. Use
// the "indirect access to member" operator -> to access members of the
// pointed-to object:
fruit->some_method();
}
The advantage of using this approach (vector of unique_ptr objects) is that your apple and banana objects are automatically destroyed when the vector is. Otherwise, you have to delete them manually, and that is a very error-prone approach.

C++ sorting container of base class pointers to derived objects

I have an std::list of base class pointers, all of which point to one of the two derived object classes. An instance of the base class is never declared, and, although the base class is not abstract, every member function is declared as virtual. Consider the code below:
class A
{
public:
A();
...
//member functions
...
protected:
int common_data_1;
std::string common_data_2;
...
};
class B: public A
{
public:
B();
//member functions
...
protected:
std::string class_B_specific_data;
...
};
class C: public A
{
public:
C();
//member functions
...
protected:
std::string class_C_specific_data;
...
};
These classes are instantiated as the appropriate base class via conditional statements and stored in an std::list by the base class pointer simultaneously in the same block of code like so:
std::list<A*> ptrList;
//conditional statements either create a B or C object
//and then that object is appended to the list
if (blahblah = true)
A* entry = new B();
else
A* entry = new C();
ptrList.append(entry);
I need to perform an insertion sort on this container of base class pointers based on an integer value that both derived classes inherit; however, in my previous attempts and upon inspection with a debugger tool, I find that my insertion sort algorithm properly makes the correct comparisons when accessing the integer that the comparison is based on, but I am unable to swap the position of the base class pointers in the std::list. I want to sort this container of pointers so that I can easily print the data in the proper order with a simple for loop.
This is clearly the result of a misunderstanding of pointer semantics, but to much avail I have been unable to find any reference or example that elucidates or solves the issue I am experiencing.
Any result that I have found either on this site or elsewhere solves this problem by using a container of the actual objects instead of a container of pointers to the objects. But, in my case, I can't do this because my code relies on the polymorphic behavior of the base class in order to have one big list of derived objects, instead of multiple lists for each derived object. Obviously, this makes calling member functions of the correct derived class extremely easy, and I would rather not redesign the entire structure of my data if I can avoid it.
If requested, I can post snippets of my code and/or the attempts that I have made to properly swap these pointer positions inside the container; however, I am unsure if this would even be helpful, since I am clearly using the wrong syntax to handle the pointers.
I appreciate any feedback; this problem has been plaguing me for the past few weeks and it is definitely time for me to step back and ask for assistance. I have a feeling that I am over-analyzing this issue, and that is most likely what is preventing me from solving the problem.
Assuming your goal is to sort an existing container, sort has a Compare comp argument that allows your to change its default behavior. To use it, you define a functor (a class that overrides operator()) that knows how you want your pointers to be compared. In this case, you want to define one that compares the common_data_1 that the pointed-to objects have.
class Comparator {
public:
bool operator(A* left, A* right) {
//You can do whatever logic you need here, here's an example:
return (a->common_data_1) < (b->common_data_2);
}
}
Then, call sort on your list:
ptrList.sort(Comparator());
I like #IanPudney's answer, though I typically use a lambda:
ptrList.sort([](A* first, A* second)
{return first->common_data_1 < second->common_data_1;}
);
Replace common_data_1 with whatever data member or function you want to use to sort.

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.

Creating an array of unlike objects

This is a followup to my last question wherein I need an array of objects which are child classes of one base class. I was suggested I try dynamic_cast but speed is very important in this project.
Here is essentially what I am after.
class Object
{
protected:
int id;
};
class Bike: public Object
{
public:
bike();
private:
int bells;
};
class Car: public Object
{
public:
void drive();
private:
int wheels;
};
I need an array of these objects so I decided to use the base class.
// Imagine I have 10 objects and don't know what they will be
Object* objects[10];
// Let's make the first object
objects[0] = new Car;
I was told dynamic casting was a good idea. The problem is that speed is important and I have instances where I will need to do such operations as:
Car 8 references a bike at index value 3.
Is there any other workaround without dynamic_casting?
EDIT: If I populated the array with a bunch of child classes, how could I access the data of a child class at a specific index. In other words, imagine a bike is at index 8. How could I get the int bells from that object with just the array and index.
It depends on what else you're doing, but you could have an array of structures that store an enumeration that specifies what object type it's storing along with an object pointer.
IE:
class CObject;
enum EObjectType
{
OT_Bike,
OT_Car
};
struct SObjectInfo
{
EObjectType Type;
CObject* Object;
};
When iterating through your array, you can check the type of the object, then static cast the object pointer to the appropriate derived type. I use this approach extensively where it can't be avoided and run-time identification of an object type is absolutely necessary within a generic container.
Why do you need to store objects of different classes in the same array, though, without using polymorphism and virtual methods?
First of all if you need it to be very fast do not create it on the heap with operator new. You need to create them locally if possible.
If you are sure that there will be always your objects than you can change casting to static_cast which is a lot of faster solution.
For me the best idea here is to use Interfaces with pure virtual methods. like:
Class Objects //interface
{
public:
virtual void ride() = 0;
}
and then use a interface as a base class. It is very common in the programming.
If the Objects are unlike, why have a base class?
This link might be of help: http://www.codeproject.com/Articles/23304/High-Performance-Heterogeneous-Container
It looks that your problem requires some run-time overhead, no matter how the implementation would look: this is because at some point the program needs to decide what type it actually stores. Note that you have more alternatives to introducing a bit artificial inheritance, provided you can afford using Boost:
Boost.Variant - if you know all the types that you will be storing in advance
Boost.Any - if you do not

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)