Associating types with each other - c++

I have an Action class from which I derive several subtypes. Now, I need to associate some of these subtypes with each other, in a one-to-many relationship. The idea is that some types of Action subtype will make other subtypes available/unavailable (i.e. I also need to create them on the fly). Since in a language like C++ you cannot store type variables the only thing that makes sense is an association of string typenames.
Has anyone met a similar situation? And if so, would you simply use a non-unique associative container like std::multimap and then manually hardcode a huge switch statement for the string-type association?
Example: An action of type Attackwill eventually make Retreat available to its actor, as well as others, like Charge etc. Each action constructor takes at least one Actor reference, but it may also take other, unknown at compile-time, parameters. This last bit makes it very difficult to model this as a decision/action tree... in other words, it seems like I have to build the decision tree during runtime.

Related

Future-proofing data types(i.e creating structs with only one member in hopes they can be expanded later, when needed)

Say I want to create a list of variables/objects to store something very specific(say the coordinate for where an enemy needs to spawn in a videogame), at first I would only need a simple point in space to store this information but later on I may want to add the enemy type and other data specific to each element of this list. Is it good practice to write a whole new class or struct with only just the initial data member I need in hopes that whenever I need to update the list with more data per element I can just add members to this previously redundant struct/class? Furthermore, is packaging an already existing type into a new one in the spirit of being more descriptive something that actually helps code readability?
Sounds like a classic case for some good old object orientated programming.
So the idea would basically be that you have your simple struct/class with, as mentioned in your example, coordinates. If you would want to add another enemy with some extra attributes to be stored you would go ahead and create a new class/struct that inherits from the very basic class. That way you get all the attributes the basic class had in your new class plus you can define new ones.
That way you have a good structure in your code and it is easy to understand what is going on. Scalability and reusability also profit greatly from this, which is why this concept is state-of-the-art.
This might sound a little confusing at first, but I recommend to read up on inheritance and object oriented programming in general. I promise it is not too hard once you get used to the thinking patterns.

C++ Language Issue (Motivated By Google Protocol Buffer Application)

My question is probably just a simple question about using the c++ language, but the background/motivation involves networking code, so I'll include it
Background:
I have an application with a bunch of balls moving around according to various rules. There is a server and a client that should be as synchronized as possible about the state of each ball.
I'm using Google's Protocol Buffers to create message objects that allow the client to set up or update each ball. Balls have different states, and each ball might need to be transmitted to the client using a different message class generated by GPB. For example, one type of ball updates its position using a fixed acceleration vector, so the message corresponding to that type of ball would have position,velocity, and acceleration.
I want to store these message objects in a data structure that organizes them by position, so that clients can access only message objects that are nearby. But each message has a different class type, so I don't know how to correctly put them all in a structure.
If I were hand-writing the message classes, I would make them all be subclasses of an abstract Message base object, with an enum type member. Then I would store the messages as unique_ptrs to the abstract class and then do a static cast by the type enum whenever I needed to work with each object individually. Ideally, since I need to serialize the message objects (they each have a serializeToOutputStream(..)) function, I would make this function an abstract member of the base class and have each of the particular message classes override it, so that I could avoid a cast in some situations.
The problem is that I am not hand-writing these classes. They are generated by google's compiler. I'm sure such a situation has arisen before, so I wonder how I should deal with it in an elegant way, if there is one.
Language-Only Version of Question:
I have a fixed set of generated classes A,B,C,D... that all have a few common functions like serializeToStream(). It would be very tedious to alter these classes since their sources are generated by a compiler. I would like to store unique pointers or raw pointers to these objects in a data structure of some kind, like an std::map or std::vector, but I don't know how to do this. If possible it would be great to call some of the functions that they all have without knowing which particular class I was dealing with (such as if I call the serialize function on all of them in a vector).
There is not good way to solve your problem. Only nasty haks. For example you can store pointer to object and pointer to method of some fake type in your map. But then you must cast your classes and pointers of its methods by reinterpret to this fake type. You must remember that all who will read that your code will scold you and may be better to find the approach to create common base.

Storing/uncoupling behaviour

I am making use of the Type Object pattern (as described on gameprogrammingpatterns.com), which was just what I needed to avoid redundancy of data and make it easier to reduce hardcoding. In short I have something like this:
class Action
{
// ...
ActionType& Type;
}
where ActionType is the type object that holds static data for this particular type of Action. There will be several instances of Action, so the memory expenditure is reduced considerably (as compared to storing the type data in each Action instance). It also makes it possible to load action type parameters from a script, but it doesn't work with behavior.
I'm finding it necessary to derive from Action to support different behavior, which kind of defeats the purpose. I could of course use some sort of callable object to parametrize behavior in the ActionType object, but that would still necessitate hardcoding.
How does one go about something like this? Scripting? If that is the way, is it possible to precompile a script for better performance in the release?
Update: To clarify, each Action has an OnUpdate() function that I want to customize for every type of action, without involving inheritance and hardcoding.

Inheritance with composition

I am designing a system, I have not yet implemented first I am just diagraming it and then will code it, I want to ask one simple question:
What to do when we are using both inheritance and composition at the same time?
For example, in a hotel, there are 2 kinds of room standard room and Twin room let us say. For this I can use inheritance concept and these 2 kinds of rooms will be derived class but i can also use composition and will make seperate class for standard and twin room, then will use this is my hotel class.
What should I do?
This question is kinda vague and there are many details missing, yet I'll share some ideas...
First thing: while working on design of your application, what matters the most are the requirements.
You need to try to identify entities that will have some meaning in your system first. Let's say you know that there will be Hotel and Room. Note, that this relation is a composition already, mainly because:
room can be part of only 1 hotel, it is not shared among multiple hotels
once the hotel is destroyed, so are all rooms in it
in C++, composition usually means "by value", i.e. class Hotel could have Room room; that would be an object with automatic storage duration with its lifetime tied to the lifetime of instance of Hotel, with multiple rooms you could just put them to the vector yielding the same relationship:
class Room { ... };
class Hotel {
public:
std::vector<Room> rooms;
};
(By the way, an aggregation would be most likely represented by a pointer or reference). This is another good example of composition:
If you know that there will be different kinds of rooms, first questions should be: will these objects have different behaviour? will my system treat them in different way? ...maybe you don't need to go for finer granularity than Room and everything that a concrete room will be specific with will be expressed with its attributes - size, number of beds, maybe dozens of boolean "has" flags ("has aircon", "has TV", "has microwave", ...), maybe all of its properties can be expressed with simple "type", values of which you would put into the enum.
I the case you site, I would have a room_type property on the room class, and I would set the type of the room_type property to an enumerated type with possible values of STANDARD and TWIN.
As long as there are not significant behavioral differences depending upon this type field, I would keep it simple.
If there are complicated behaviors, like predicting clean up based upon number of beds, changing pricing, and so on, I would use an abstract base class CRoom, and inherit CStdRoom and CTwinRoom from that, possibly setting a constant num_of_beds property in the class constructors.
You shouldn't use language inheritance to model business requirement inheritance. It just makes it too hard to modify or extend the business model. Language inheritance is for implementing features of your model, not the model itself.
Instead, derive all your objects from 'business object' or similar, to encapsulate common internal behaviour such as serialisation. Your classes can have types and you can use typeinfo, or you can use an explicit type field. Either way links between objects, whether inheritance-like or composition-like should be pointers (or index id fields) and collections (of pointers or index ids). [Your code snippet is fine, but pointers complicate memory management which integer ids avoid.]
Complicated behaviours should belong to other classes such as the Pricing, Cleaning, etc. There are other patterns to use in setting the relationships between business objects and business actions, but again avoid crystallising them using language features. You will regret it, if the system grows or changes even a bit.

C++ class design from database schema

I am writing a perl script to parse a mysql database schema and create C++ classes when necessary. My question is a pretty easy one, but us something I haven't really done before and don't know common practice. Any object of any of classes created will need to have "get" methods to populate this information. So my questions are twofold:
Does it make sense to call all of the get methods in the constructor so that the object has data right away? Some classes will have a lot of them, so as needed might make sense too. I have two constrcutors now. One that populates the data and one that does not.
Should I also have a another "get" method that retrieves the object's copy of the data rather that the db copy.
I could go both ways on #1 and am leaning towards yes on #2. Any advice, pointers would be much appreciated.
Ususally, the most costly part of an application is round trips to the database, so it would me much more efficient to populate all your data members from a single query than to do them one at a time, either on an as needed basis or from your constructor. Once you've paid for the round trip, you may as well get your money's worth.
Also, in general, your get* methods should be declared as const, meaning they don't change the underlying object, so having them go out to the database to populate the object would break that (which you could allow by making the member variables mutable, but that would basically defeat the purpose of const).
To break things down into concrete steps, I would recommend:
Have your constructor call a separate init() method that queries the database and populates your object's data members.
Declare your get* methods as const, and just have them return the data members.
First realize that you're re-inventing the wheel here. There are a number of decent object-relational mapping libraries for database access in just about every language. For C/C++ you might look at:
http://trac.butterfat.net/public/StactiveRecord
http://debea.net/trac
Ok, with that out of the way, you probably want to create a static method in your class called find or search which is a factory for constructing objects and selecting them from the database:
Artist MJ = Artist::Find("Michael Jackson");
MJ->set("relevant", "no");
MJ->save();
Note the save method which then takes the modified object and stores it back into the database. If you actually want to create a new record, then you'd use the new method which would instantiate an empty object:
Artist StackOverflow = Artist->new();
StackOverflow->set("relevant", "yes");
StackOverflow->save();
Note the set and get methods here just set and get the values from the object, not the database. To actually store elements in the database you'd need to use the static Find method or the object's save method.
there are existing tools that reverse db's into java (and probably other languages). consider using one of them and converting that to c++.
I would not recommend having your get methods go to the database at all, unless absolutely necessary for your particular problem. It makes for a lot more places something could go wrong, and probably a lot of unnecessary reads on your DB, and could inadvertently tie your objects to db-specific features, losing a lot of the benefits of a tiered architecture. As far as your domain model is concerned, the database does not exist.
edit - this is for #2 (obviously). For #1 I would say no, for many of the same reasons.
Another alternative would be to not automate creating the classes, and instead create separate classes that only contain the data members that individual executables are interested in, so that those classes only pull the necessary data.
Don't know how many tables we're talking about, though, so that may explode the scope of your project.