How to create an array in which the type is abstract but the objects will be derived classes (C++) - c++

my issue is that i need to be able to create an array of 100 objects. However the objects could be one of four different objects all of which are ultimately derived from an abstract class. I could use 4 separate arrays but it appears as if my teacher only wants us to use one array.
Class structure is : DVD & VHS are derived from Video, CD & Cassette are derived from Audio, Audio & Video are derived from Media. Audio, Video, and Media are all abstract.

You'll have to use pointers. You can't copy or assign derived types, at least not through a declaration of the base type.

for an array
- the size of type must be known (for reserving the contigous memory)
- the type may not be an abstract class (for initializing the class must be instantiable)
the only solution for an array is to use pointer indirection, as the size of a pointer is known. you can use raw or smart pointers to base class. when using raw pointers you have to take care of the object destruction before deleting the array. when your array itself resides on the heap do not forget delete [].
to overcome these issues a standard container like vector should be used with a smart pointer. only then a simple deletion of the container deletes all the media objects. if the container shall reside on the heap you should as well use a smart pointer to hold it.
make yourself familiar with these two concepts. and if you have no idea what types are best use vector and shared_ptr until you know better.
forgot to say: vector you find in the standard library, shared_ptr you find ther only in a C++11 compiler. if you have an older compiler you have to include boost libraries.

Related

Scenarios where we force to use Pointers in c++

I had been in an interview and asked to give an example or scenario in CPP where we can't proceed without pointers, means we have to use pointer necessarily.
I have given an example of function returning array whose size is not known then we need to return pointer that is name of the array which is actually a pointer. But the interviewer said its internal to array give some other example.
So please help me with some other scenarios for the same.
If you are using a C Library which has a function that returns a pointer, you have to use pointers then, not a reference.
There are many other cases (explicitly dealing with memory, for instance) - but these two came to my mind first:
linked data-structures
How: You need to reference parts of your structure in multiple places. You use pointers for that, because containers (which also use pointers internally) do not cover all your data-structure needs. For example,
class BinTree {
BinTree *left, *right;
public:
// ...
};
Why there is no alternative: there are no generic tree implementations in the standard (not counting the sorting ones).
pointer-to-implementation pattern (pimpl)
How: Your public .hpp file has the methods, but only refers to internal state via an opaque Whatever *; and your internal implementation actually knows what that means and can access its fields. See:
Is the pImpl idiom really used in practice?
Why there is no alternative: if you provide your implementation in binary-only form, users of the header cannot access internals without decompiling/reverse engineering. It is a much stronger form of privacy.
Anyplace you would want to use a reference, but have to allow for null values
This is common in libraries where if you pass a non zero pointer, it will be set to the value
It is also a convention to have arguments to a function that will be changed to use a pointer, rather than a reference to emphasize that the value can be changed to the user.
Here are some cases:
Objects with large lifetime. You created some object in function. You need this object afterwards (not even copy of it).
But if you created it without pointers, on stack - after function would finish, this object would die. So you need to create this object using dynamic memory and return pointer to it.
Stack space is not enough. You need object which needs lot of memory, hence allocating it on the stack won't fit your needs, since stack has less space than heap usually. So you need to create the object again using dynamic memory on heap and return pointer to it.
You need reference semantics. You have structure which you passed to some function and you want the function to modify this structure, in this case you need to pass a pointer to this structure, otherwise you can't modify the original structure, since copy of it will be passed to the function if you don't use pointers.
Note: in the latter case, indeed using pointer is not necessary, since you can substitute it using reference.
PS. You can browse here for more scenarios, and decide in which cases are pointer usages necessary.
pointers are important for performance example of this are for functions. originally when you pass a value in a function it copies the value from the argument and stores to the parameter
but in pointers you can indirectly access them and do what you want

Any good techniques for designing copy constructor for class with some pointers and many data members

I am faced with a class that must use a few pointers (due to reliance on an old library, it is not easy to use smart pointers here) and the class also contains a large amount of non-pointer data members that may grow as the project progresses.
Because of the pointers, I want to write my own copy constructor. Because of tedium and difficulty in maintenance, I do not want to write out an initialization list that includes all the non-pointer data members and update it each time a new member is added.
It would be great if I could somehow rely on the default copy constructor and then just modify it for the few pointers, but I am not sure that this is possible? Is there a way to do this or some other technique for dealing with this situation?
Some thoughts that may answer my own question.
The data members could by places in a separate class. Then the original class could just contain one object of the data class and do a default copy of it.
Anything better?
If your class doesn't own the raw pointers, just shallow copy them and call it all good.
If your class does own the pointers, go ahead and use an appropriate smart pointer and pass the raw pointer from it into your external library's API.
Finally if you and the library share ownership, ditch the library and find one with a sane interface. Or if you absolutely must, put the pointer members of your class into a special_library_pointer_holder class that knows how to properly copy/assign/etc each pointer than it holds with respect to your external library and then contain just the special_library_pointer_holder in your original class.
I think the best approach here is to let smart pointers do the job and follow The Rule Of Zero.

C++, array of objects (from different classes) without Stl & Boost

I want to create in C++ an array which can hold objects of diffrent classes.
It's a part of my hometask and one of the conditions is that i can't use Stl, Boost & etc.
You should create Base class and derive your class from Base class. And as a result you can create array Base* array and put there all derived classes.
You could store pointers to void* in your array and cast your objects to void*. But you should not do this!
If possible you should derive all your objects from a Base Class and store pointers to Base*. This is the better way to solve this problem.
Does the same container have to hold objects of the same type at the same time? If so, does it have to be able to hold any type? If so, your only solution is to use void* and store pointers to the objects you want to store.
If one container only has to hold one type of object, then you can do this using templates. If the same container has to hold different types of objects but you can place restrictions on the types it can hold, then you can make a requirement be that it derive from some Base class, and make an array of Base*.

dynamic_cast reference to base class in stl container

Is it possible to store a bunch of objects by their base class in say an std::list without pointers. I would really like the objects to be held in the container, then retrieve a pointer to the object in the container and dynamic_cast it to correct derived class.
I have it working fine using pointers. Like (super simple version):
class IComponent
{
virtual ~Icomponent(){}
}
class PositionComponent: public IComponent
{
//...
float x, y;
}
std::list<IComponent*> CList;
//...
// fill the list
// put reference to object in pComponent
//...
PositionComponent* position = dynamic_cast<PositionComponent*>( pComponent)
position->x = 346452.235612;
But the memory management is a huge pain. My actual structure is a
map<enumValue, map<int, IComponent*> >
I get the feeling I can't use the objects themselves because when I add any derived component into the list the extra data will be cut off and leave me with the base class only. This didn't figure this until I tried static_cast instead and it crashed.
Can answer my original question and/or confirm my feelings on the matter. Thanks!
to minimize pain of manual memory management use smart pointers: std::unique_ptr if your compiler already supports it or boost::shared_ptr, but not std::auto_ptr that is not supposed to be used in containers
As you guessed, when you stored an object in a container by value, it gets sliced and the data is chopped off.
If you only need to store one data type (you only show one in your code), then you can make the container hold that type.
If not, you really are stuck using pointers. You can make the memory management much easier by using a smart pointer, or if appropriate, a boost ptr_container of some sort.
Further you might want to think if you need to spend one more iteration considering your design to provide an interface that doesn't require doing a dynamic_cast to get the original type back out again.
Is it possible to store a bunch of objects by their base class in say
an std::list without pointers.
This sentence seems to be contrdicted in C++ point of view IMO. Because STL container can only hold same type of object, if you put derived object into a base type container, it got sliced.
So the apparent normal solution is to use container to hold base type pointers like you did(u could use boost/std smart pointer for memory management)
If you really want to store different objects in one STL container, you may want to consider use boost::any.

Storing objects in vector

Is it possible to have a vector without specializing it?
My problem is: I have an abstract class N4GestureRecognizer
and a couple of subclasses of it.
So in a Controller class I want to have a vector<N4GestureRecognizer> recognizers_ but since it is abstract I cannot.
How can I store this recognizers in a vector or collection or list or whatever is loop-able in standard c++?
Store them as pointers. Either pure pointers or some smart pointer class.
EXTRA
Actually, pointers are the only way even if the class is not abstracts, but is subclassed and child classes are intended to be used in the vector. Why: std::vector allocates sizeof(T) bytes for each element, but sizeof(derivedFromT) could be bigger than sizeof(T). You will be able to push a child object into the vector, but it can cause unpredictable issues at run time.
Managing vectors of pointers is a pain, of course, but as far as I remember, boost contains some smart pointers to simplify the task.
What you need is a std::vector< std::shared_ptr<N4GestureRecognizer> >.
If your std lib comes without std::shared_ptr (it's part of the next C++ standard, expected to be published next year), it might come with std::tr1::shared_ptr, which is the same (as a addition to the current C++ standard by the official Technical Report 1). If that also fails, there's always boost, which has boost:shared_ptr (which is the predecessor of std::tr1::shared_ptr and std::shared_ptr).
Note: Don't use naked pointers (std::vector<N4GestureRecognizer*>). There's almost no way to make this safe so that it doesn't leak.