Is there a way to add a pre created class to a vector? - c++

First off, I'm new to c++, currently learning it online.
I greatly appreciate any help...
I have a vector of classes set up for vehicles, however it should also contain derived classes for vehicles of different types (car, truck, van).
My class is set up to have functions to gather user input and assign that to different variables, I do not use the constructor for this. Is that wrong?
In my main this all works fine and dandy but when I go to add the class to the vector I run into issues, first off, My instructor informed us to use smart pointers for this, so I initialize my vector like so...
vector<unique_ptr<Vehicle>> vehicles;
This is how I'm adding classes to that vector...
// For base class...
vehicles.push_back(make_unique<Vehicle>());
// For derived class...
vehicles.emplace_back(make_unique<Car>());
This is where I am stuck, adding the class this way will cause it to be called and therefor the constructor called as well. What I would like to do is just add a class that I have already created and defined beforehand, for example..
// Functions to gather user input, validate and display...
Vehicle vehicle;
vehicle.getMake();
vehicle.validateName(vehicle.make);
vehicle.getModel();
vehicle.validateName(vehicle.model);
vehicle.displayVehicle();
vehicles.push_back(/* Somehow add 'vehicle' */);
Thanks for any help, I understand this might be the wrong way to do this, I was just struggling to find a solution and this is currently where I am at.

My class is set up to have functions to gather user input and assign that to different variables, I do not use the constructor for this. Is that wrong?
A constructor shouldn't do lots of things, and never prompt for user input… but, at the same time, it should not be possible to have a "half-ready" object at any point. I suggest you gather all your user input first, then pass it into the constructor so your object is ready to go in one step.
(I have not shown this in the following example.)
This is where I am stuck, adding the class this way will cause it to be called and therefor the constructor called as well. What I would like to do is just add a class that I have already created and defined beforehand, for example..
Your vector contains unique_ptr<Vehicle>s, so you'll want to start off with one:
std::unique_ptr<Vehicle> vehicle = std::make_unique<Vehicle>();
vehicle->getMake();
vehicle->validateName(vehicle->make);
vehicle->getModel();
vehicle->validateName(vehicle->model);
vehicle->displayVehicle();
vehicles.push_back(std::move(vehicle));
Notice that all the vehicle. are now vehicle->, because vehicle is no longer an actual Vehicle but instead a pointer to one.
std::move is needed because unique_ptrs are not copyable, only moveable.
Taking my advice from the start of the answer, this gets somewhat simpler:
std::string make = GetMake();
ValidateName(make);
std::string model = GetModel();
ValidateName(model);
vehicles.push_back(std::make_unique<Vehicle>(make, model));
vehicles.back()->displayVehicle();
I've moved the displayVehicle call to the end, because it shouldn't make a difference to your output, but allows us to do the "construct Vehicle" and "put it into vehicles" steps simultaneously.
This approach assumes that you have altered your constructor to take make and model, and set up free function GetMake(), GetModel() and ValidateName() to do those tasks.

Related

How to store multiple class's different objects inside of a vector?

So my code I want to make a vector that takes any object that is from a derived class of "PLATFORM".
So Platform is my base class, and I have things like books, games, tv shows, and other things. I want to put all of these inside of a single vector. It needs to be done this way, so there is no other way to go about it.
So I want a vector to contain... an object from books, an object from games, etc...
I've been reading around on forums, and I consistently see people suggesting the use of boost::any or boost::variant. I'm trying to avoid using boost at the moment.
I've seen multiple suggestions like...
doing something like
Book tmpBook;
tmpBook.setName("ERAGON");
//I do the above just to get a object to use
vector<Platforms*> platforms
platforms.push_back(tmpBook)
cout << platforms.at(0).getName() << endl;
I expected to see it print out ERAGON, but I got an error...
error: request for member 'getName' in 'platforms.std::vector<_Tp, _Alloc>::at >(0u)', which is of pointer type... And it goes on from here.
I feel like i'm missing something very crucial here, so please help!
My classes are set up simply with base class "Platform" with a getName() and setName() virtual method and a protected string name variable.
The derived classes basically just have the setName() and getName() versions for their class.
Later, I plan to add more details that further define each class with more defining features for their respective objects. like a book having a page number and such...
I've also seen the suggestion of using the sharedptr, but it seemed so complicated...
Try
Vector<Platforms> platforms
I cant get that why are you using pointer in vector

Creating a unique ID for class types C++

My goal here is to create a unique ID (starting a 0) for each child of a specific class. I'm not sure if it is possible in the way i want, but i figured i'd ask here as a last resort.
Some context:
I'm creating my own 2D game engine and i want it to have an ECS as it's back bone (Before anyone says anything, i'm doing this as a learning experience, i know i could just use an already existing game engine). My idea is that each class that implements the 'EntityComponent' class should have a unique ID applied to it. This needs to be per child, not per object. I want to use this ID as the index for an array to find the component of an entity. The actual ID that each Component gets is unimportant and each component does not need to be assigned the ID every run time.
My hope is there is some way to create something similar to a static variable per class (That implements the Entity Component class). It needs to be quick to get this value so doing an unordered_map lookup is slower than i would like. One thing i do not want to do is setting the ID for every component myself. This could cause problems once many components are made and could cause problems if i forget to set it or set two components to the same ID.
One idea i had was to make a variable in EntityComponent called ID (And a getter to get it). When the entity is constructed it looks up an unordered map (which was made at run time, assigning an ID to each class) for what ID it should have. The price of looking up once at construction is fine. The only problem i see with this is there is a lot of redundant data (Though overall it seems it would account to a pretty small amount). With this, every single transform component would have to store that it its ID is x. This means potentially thousands upon thousands of transform components are storing this ID value, when only 1 really needs to.
Basically i am after an extremely quick way to find an ID for a class TYPE. This can be through a lookup, but it needs to be a quick lookup. I would like something faster than unordered_map if possible. If this can be done through compile time tricks (Maybe enums?) or maybe even templates i would love to hear your ideas. I know premature optimisation is the bad, but being able to get a component fast is a pretty big thing.
What i'm asking might very well be impossible. Just thought i'd ask here to make sure first. I should also note i'm trying to avoid implementation of this in the children classes. I'd like to not have to set up the same code for each child class to create an id.
Thank you.
In order to get something corresponding to the actual type of an object, it either needs to be in the object itself or accessed via a virtual function. Otherwise the type will be determined by the type of the variable it is associated with.
A common option when speed and size are both important is to have an integer identifier associated with each type (when the full type list is known at compile time) and use that integer value in a specific way when you want to do something based on the type.
The integer mechanism usually uses an enum for generating the corresponding value for each type and has that field in every object.
The virtual method variety, I've used boost::uuid and a static data member in each class and a virtual method get'er for it.
Declare a virtual function newId() in EntityComponent.
Implement this function to get and increment a static variable in each class, which children you want to have a unique Id.
Assign Id in the constructor:
mId = newId();
don't know this if this is what you meant and i know this is an old post however this is how im currently dealing with a similar issue, maybe it will help someone else.
(Im also doing this as a learning experience for uni :) )
in the controlling class or its own utility class:
enum class EntityType{ TYPE_ONE = 0, TYPE_TWO =1};
in class header:
#include "EntityType.h"
class Whatever{
public:
inline void getType(){return _type;}
OR
inline void getType(){return EntityType::TYPE_ONE;}
private:
EntityType _type = EntityType::TYPE_ONE;
};
Hope this is helpful to anyone :)

C++ design issue. New to templates

I'm fairly new to c++ templates.
I have a class whose constructor takes two arguments. It's a class that keeps a list of data -- it's actually a list of moves in a chess program.
I need to keep my original class as it's used in other places, but I now need to pass extra arguments to the class, and in doing so have a few extra private data members and specialize only one of the private methods -- everything else will stay the same. I don't think a derived class helps me here, as they aren't going to be similar objects, and also the private methods are called by the constructor and it will call the virtual method of the base class -- not the derived method.
So I guess templates are going to be my answer. Just looking for any hints about how might proceed.
Thanks in advance
Your guess is wrong. Templates are no more the answer for your problem than inheritance is.
As jtbandes said in comment below your question, use composition.
Create another class that contains an instance of your existing class as a member. Forward or delegate operations to that contained object as needed (i.e. a member function in your new class calls member functions of the contained object). Add other members as needed, and operations to work with them.
Write your new code to interact with the new class. When your new code needs to interact with your old code, pass the contained object (or a reference or a pointer to it) as needed.
You might choose to implement the container as a template, but that is an implementation choice, and depends on how you wish to reuse your container.
Templates are used when you want to pass at compile time parameter like values,typenames, or classes. Templates are used when you want to use exactly the same class with the same methods, but applying it to different parameters. The case you described is not this I think.
If they aren't goign to be similar objects you may want to create a specialized class (or collections of function) to use from the various other classes.
Moreover you can think of creating a base class and extending it as needed. Using a virtual private method should allow you to select the method implementation of the object at runtime instead of the method of the base class.
We may help you more if you specify what does they need to share, what does your classes have in common?
The bare bones of my present code looks like this:
class move_list{
public:
move_list(const position& pos, unsigned char ply):pos_(pos),ply_(ply){
//Calculates moves and calls add_moves(ply,target_bitboard,flags) for each move
}
//Some access functions etc...
private:
//private variables
void add_moves(char,Bitboard,movflags);
};
Add_moves places the moves on a vector in no particular order as they are generated. My new class however, is exactly the same except it requires extra data:
move_list(const position& pos, unsigned char ply,trans_table& TT,killers& kill,history& hist):pos_(pos),ply_(ply),TT_(TT),kill_(kill),hist_(hist) {
and the function add_moves needs to be changed to use the extra data to place the moves in order as it receives them. Everything else is the same. I guess I could just write an extra method to sort the list after they have all been generated, but from previous experience, sorting the list as it receives it has been quicker.

C++ - trying to point each sub-class to the main class in order to contain all information in a vector

Basically, Im writing a small database/inventory system for a game. The item class and its sub-classes (weapon, armor, consumable, etc) are all finally up and working. My vector for inventory is written within a separate inventory class (allows more than one inventory - i.e. enemies can have them too!) and at this point, the inventory is FAR from written - there is still no drop function, etc.
but im taking this one step at a time because its a learning experience.
basically I believe in this case, pointers are the answer. this code seems to work (have not tried it yet)
Weapon DebugDagger{ 1, "Debug Dagger", "Debug Dagger given to you by Help", 25 };
Armor DataCloak{ 2, "Data Cloak", "Data Cloak given to you by Help", 10 };
Item *pItem = &DebugDagger;
Weapon *pWeapon = &DebugDagger;
InventoryManager PlayerInv;
PlayerInv.pickupItem(pWeapon);`
in this case, pickupItem(Item*) is taking a static Item type - which is the base class for my function, where the weapon being added to the inventory is a sub-class (class Weapon : public Item{})
the way this is written seems to hack together a solution, but it would be MUCH easier if I could just write the pointer into the class functions themselves so that EACH item created in a sub-class automatically will create a pointer of itself to the base class so I can add it into the inventory subsystem. Is there a way to do this from Within the class? so that EACH member gets a pointer created automatically upon class creation? When I try to use the name variable in the constructor to do this, it does not work, as it seems I have to create the member BEFORE making a pointer, so I dont see how to do it at the same time anticipating a new member being created.
I mean, I'm all for other more effective ideas than a std::vector inventory; for an inventory - I think some function that actually can simply accept the members of any class and record them would be FAR more effective in the long run, but I do not believe this is possible - I think that creating pointers to Item from the sub-classes would still be necessary - seeing as, really, its all items, with each sub function having a single extra specifier ONLY being used for its own function, weapon has attack, consumable has restoration, etc -and its ALL integers, so really those are the same as each other almost, but for function reasons, like equipping, using, classifying, they each get a separate type I suppose I couldve made a SpecialItem subclass to cover it all, but that would be very ambiguous, and leave little room for innovation should a specific type need modification later.
I just dont see it if there is an alternative. if there is direct me and I will read voraciously until I find understanding of it.
Not sure if i got the point, but a pointer to the subclass (Weapon) is already a pointer to the base class (Item).
So you can store all your items (Weapon : Item, Arnmor : Item, ...) in your
std::vector<Item*> Inventory
It does not seem to work this way, because by default NO pointer is being created, in this instance I Had to write one on the fly after creating the Item in order for it to push_back.
otherwise it tells me class Weapon cannot be converted to Item * and wont compile.
so it seems to me that I CAN"T store them into the vector -- for that to work it would have to be
std::vector<Weapon*> Inventory
basically I need the functionality of
std::vector<Weapon*> Inventory
std::vector<Armor*> Inventory2
std::vector<Consumable*> Inventory3
std::vector<Item*> Inventory4
except I need it in ONE single inventory class...
my problem is right now I ONLY have
std::vector,
and NO other class type is ALLOWED to be inserted into this slot, because I have to either convert the type manually (since memory can't do it on its own, the special characteristics have to be dropped), or create a pointer to Item* so that when I insert the POINTER like this:
Inventory.push_back(POINTER);
it will BELIEVE the weapon is an Item, and go ahead with the operation.
otherwise
Inventory.push_back(WEAPON), etc do not work... only Inventory.push_back(Item*)
I dont know if this has been any more clear, but it should make it understandable why I need the pointer. Since I cannot cast a Weapon or even a Weapon * as an Item, I have to create a pointer to Item somewhere in the class function, so that way I have some variable I could automatically pop into the push_back function INSTEAD of the member of the class itself - I sort of have to cloak a weapon or potion as a basic item in order to get it to fit into the vector, because it only accepts basic items as is.
Well, either way - the code ended up being NONFUNCTIONAL IN ENTIRETY.
regardless of this, I need a way to create a database of all members of each type of class.
I need the functionality of a vector, that will work with any type -- or a method to get a vector to accept any type.
I gave up on this method, because it just will not work to have one vector alone.
now Im working on a 3 vector class of obtained item names, quantities, and IDs.
it seems a bit** to figure out how to associate the 3 and also scan through them in unison to make data make sense (I.e. see if item name x, id 32 is in inventory, if it is, allow user to examine such item for details).
this is my first big project really. its a doozy for me.

class DisplayManager: vector<string>

I'm working on an assignment for my C++ programming class. The assignment is basically to take code given to us and fill it in to make a working, low level, text editor. Problem is, I've never seen this syntax before. If I knew what it were called, I could find information about it, I'm sure. It might even be in my textbook, I just haven't been able to find it...
Anyway, if anyone could point me in the right direction for learning about this type of class, I'd appreciate it greatly.
class DisplayManager: vector<string>
(A display is a vector of strings called "rows". Each line of the document may occupy one or more rows.)
This is called inheritance. Please have a look here.
Your DisplayManager class inherits from vector<string>. That means, it is essentially the same as vector<string>, plus the changes you make in the class body. However, since you did not add the public keyword, users of the class will not be able to access the members it inherited from vector.