allocating an object of type abstract class c++ - c++

I am trying to make and array of size_t size of type Media which has a virtual method, in class MediaManager
but it is giving me this error
But I have implemented that virtual function in all sub classes, e.g Book is subclass of Media
MediaManager is just a class that act as a container to all type of Media.
here is my Media class
Here is MediaManager class, I want to initialize that Pointer to Media object array in Constructor to given size.
can you tell me please, what am i doing wrong.
I am trying to make array of type Media in MediaManager constructor, that would hold any type of Media,
and then I could use that array for further process.
I cannot use vector because question ask to must use array.

new Media[size]() is asking for an array of Media. But Media is an abstract base class which cannot be constructed. So you need to make an array of pointers to Media, like new std::unique_ptr<Media>[size]. Then you can populate the pointers in that array with things like std::make_unique<Book>().

Related

I have a vector of Base and Derived Class Objects, but I can't access data members inherited by derived objects that are stored in the vector

Bear with me, I'm relatively new at C++.
Here is my project. I want to essentially create a simple game of chess.
I've got a base class gamePiece, which I'm thinking will eventually become an abstract class ( but right now it isn't)
The base class gamePiece has a bunch of data members in it: colorOfPiece, rankOfPiece, fileOfPiece, etc. It also has a function, void displayPieceInfo() which simply displays all of these values on the console via cout.
I am planning on having a number of derived classes from this one. Right now I have a "rook" subclass.
I want to add various types of pieces in a single vector, so I can later traverse it with an iterator.
Here is the problem I am running into.
vector<gamePiece> vectorOfAllGamePieces;
vector<gamePiece>::iterator itGamePieces;
I push_back a Rook into the vector as the first element. All the constructors look like they are running fine, initializing the variables. Yet when I try to run the display function on the first element, the strings are empty/unitialized.
itGamePieces=vectorOfAllGamePieces.begin();
itGamePieces->displayPieceInfo();
If I were to push in a generic gamePiece into the vector instead, everything would display properly.
Am I allowed to even have a vector like this with mixed types of objects -- for example, an object of a derived class, an object of the parent class, an object of a second class derived from the same parent
And if so, why do you suppose the values of the data members aren't showing up properly, even after I have set them in the constructor?
Not really, because of slicing. When you add a derived object to a vector<gamePiece>, it gets sliced and a gamePiece object is actually added to the vector.
You'll need to use a vector of (smart) pointers.
The problem is like this, Rook is a GamePiece. But You Cannot Store a Rook in a place for GamePieces. You can only cast a Pointer to Rook to a Pointer to GamePiece. So your vector must be saving NOT GamePieces but GamePiece * (Pointers to GamePieces).
std::vector<GamePiece *> vectorOfAllGamePieces;
But this could give you trouble in memory management. Another way is to store Handles without using pointers. ( a handle is something like a pointer to a pointer ). Or of course you can use smart pointers.
A quick hack will be ( this is a "hack" which is "evil" in the eyes of some people ),
std::vector<Rook> allRooks;
std::vector<Pawns> allPawns;
.....
std::vector<Queen> allQueens;
King theKing;
std::vector<GamePiece *> allPieces;
The allPieces will contain pointers to objects in the other vectors.
I think this is kind of OK when you know exactly all the types of pieces ( i guess this is chess ).

How to create an array in which the type is abstract but the objects will be derived classes (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.

Regarding: Child Class in a Array C++

Regarding: Child Class in a Array C++
Hi guys, sorry as i am stuck on some work.
Basically this is what happen
I have a parent class call vehicle and it got 2 child class call
Car and Motorcycle
Parent class have the following value:
string Name: value either Car or MotorCycle
wheels : 4 or 2 (depends is car or motorcycle)
Notes On Wheel:
wheel[0] : Fine condition
wheel[1] : need some repair
wheel[2] : Fine condition
wheel[3] : Fine condition
I wonder how do i record this all in VehicleTwoD Array
Car / Motorcycle is a child class of Vehicle, what do you guys suggest. I try to create an object of VehicleTwoD vehtwod[100];
then i do a for loop to prompt. but how do i record the object car / motorcycle into my VehicleTwoD array and how do i record the string array inside too. so every VehicelTwoD array element contains the information
Name ( Motorcycle or Car)
Wheel ( depend on name - 2 or 4)
String array - notes size depend on what is choosen
How do i record all in 1 array.
Thank you very much , i know this is polymorphic and i know this is OOP and i know i need study more. but i really stuck on this part on creating such array that can hold other array.
THANKS!
Simplifying solution by not addressing irrelevant dimensionality of the storage array.
Create an array of Vehicle pointers, and store those:
vector<unique_ptr<Vehicle>> vehicles_;
vehicles_.push_back(new Car(...));
vehicles_.push_back(new Motocycle(...));
Since we're using unique_ptr here instead of a raw pointer, there's no need to explicitly delete.
By making the class polymorphic you can declare functions on the base class and implement class-spefici functionality by providing definitions in the derived classes. This makes it possible to call methods through a pointer to the base class without having to cast to the derived type.
If you need to call methods that exist only on a derived class, then you will need to cast the pointer. This should be done using dynamic_cast, and requires that your class is polymorphic.
EDIT:
Your comments suggest that you don't know how to use a vector and would prefer to use a raw array. That's fine too. Here's a simplified example that uses a C-style array of raw pointers. Note that by using neither vector nor a smart pointer like unique_ptr you make your code more brittle and prone to errors, and you often have to use a Magic Number for the array size (which is gross).
Vehicle* vehicles_[100];
vehicles_[0] = new Car(...);
vehicles_[1] = new Motorcycle(...);

How to store a vector of objects of an abstract class which are given by std::unique_ptr?

I got a loop in which i use a function returning std::unique_ptr to an object of an abstract class. I want to store these objects into a std::vector via push_back. But since the objects are of abstract type i get the following error:
error: cannot allocate an object of abstract type
for the line
cells.push_back(std::move(*cell));
where cells is a std::vector of the abstract type and cell is of type
std::unique_ptr<AbstractType>&& cell
(I actually pass cell to a handler class)
I know that one can not instantiate an abstract type and as I'm understanding the std:move operator it need to instantiate the object somehow?
Can anybody help me how to manage the problem? Or should the function (not my part of the project) not return a unique pointer to an object of an abstract type?
You can't store AbstractType elements directly on a std::vector. You can simply store the unique_ptrs themselves in a std::vector<std::unique_ptr<AbstractType>> with cells.push_back(std::move(cell)).

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*.