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.
Related
I have a very specific... well, lets not call it a problem, lets rather call it a deadlock. I'm writing a simple 2d game using allegro5 along with c++, and have a specific problem I'd like to overcome.
Main problem:
Currently, for game loop i'm using a list container, which holds all of my objects (of type GameObject) inside, and then im iterating on it to do things like updating the objects positions, rendering and animatating sprites.
From the class GameObject (which hold generic information used for updating, rendering and memory handling methods) inherits a Creature class, which should handle things like attacking methods.
The problem that comes up is that when iterating my main list of GameObjects (which would include Creatures as well) i cannot directly use the methods of my Creatures class. Of course I understand why I cannot do that (Encapsulation).
So far I've come to few possible solutions (which, in my humble opinion are not perfect), but I would like to ask for help in helping to find easy to implement and efficient solution:
- Using a container that could hold multiple object types.
- Using dynamic_cast at some point, to cast a creature GameObjects to Creature class to temporary use Creature methods and variables (is that even possibile?)
- Setting up a second container for handling the Creature methods and variables (I would like avoid that, as then I would need a single object to be in two containers at once - when adding new types of classes 'buildings', 'obstacles' or 'arrows' thier number will grow!)
I'm a very beginner programmer, and as I understand creating a game could be kind of overkill for my level of skill, im determined to push this game forward with any means nessesary. (Especially since I've learned a lot so far)
I hope I've explained a problem in detail - i'm not posing any code here, as its more of a theoretical problem then practical one, im just iterating a GameObject list after all.
With regards,
As you've found out, containers can only hold one type of object at a time.
If that object type is a base class pointer, it can point to any object derived from the base class. However, you need to first cast the pointer to the appropriate type before you can use it's specific abilities.
You answered your own question when you brought up dynamic_cast.
You can use dynamic_cast on the base pointer stored in your container to determine if the object is actually of a different type derived from your base class.
See the section on dynamic_cast here :
http://www.cplusplus.com/doc/tutorial/typecasting/
Example
Derived* d = dynamic_cast<Derived*>(ptr_base_class);
if (d) {/* We now know that ptr_base_class holds an object of type Derived */}
else {
/// This object is not a Derived class type
}
However, if you had to iterate over your entire base class pointer list using dynamic_cast to determine if an object is of a specified type, it would be wasteful.
Here's where you answered your own question again. Keep a separate list of all Creature*s so you don't have to cast them. Yes, you will be using a /little/ more memory, but not much. Being able to iterate over the Creature list without iterating the entity list improves your performance. To make things easier, make your own container that has a list of each type of object as well as a main list of all objects. If you don't care about their derived class, iterate the main list. If you care about what class they are, iterate their specific list.
I have a question on where to create, own and destroy data.
The data itself are large tables of numbers, either randomly generated or read from the hard drive. This data is then subject to analysis, and depending on what exactly is analyzed, I have made a few wrapper like structures, which encapsulated the desired functionality. Since the wrapper can be switched in later stages, I decided against creating/reading the data inside the wrapper constructors, and just handle them in the "main" function. The wrappers then only see pointers of the data.
First of, is this common/ a good idea, or should a wrapper always own its own copy of the data it wraps around?
Well, next I made a "menu" class to better navigate through data creation/analysis choices etc, and the easiest would be to make the data part of the menu class. This doesn't feel good though, so where should I put it? Should it stay in the main class?
I hope this is understandable. If not, I can try to give a better outline of what is happening.
Thank you for reading.
You could create a data class, and wrap other classes around it. An object of the data class probably should be global or defined inside main. OTher than that - your idea seems good. WIth a data class defined, you could also pass a pointer/reference to the menu, so you wouldn't have the problem with that. Note that a menu can also be a wrapper if you wish.
It's generally a better idea to keep the details of data in a specific wrapper class (I think you mean derived class?). Your wrapper classes should be derived from an interface or abstract type. You can construct wrapper-class factories in main(), and pass the factories around to constructors (constructors of the classes that are instantiated in main()). Later when the data-specific wrapper needs to be switched on or created, invoke the factory method. The factories can own the pointers, by which I mean they call new() and delete(). Try looking up SOLID principles and see how they guide you.
I have always used structs for packaging and receiving packets, will i gain anything by converting them to classes inherited from main packet class ? is there another "c++ish" way for packaging and any performance gain by this ?
It is very general and various solutions may be available. This is related to Serialization topic and what you say is a simple model of serialization where packets contains structs which they can be loaded directly into memory and vice versa. I think C and C++ are great in this case because they allow you to write something like struct directly to stream and read it back easily. In other languages you can implement your byte alignment or you should serialize objects to be able to write them to streams.
In some cases you need to read a string stream like XML, SOAP, etc. In some application you should use structs. In some cases you need to serialize your objects into stream. It depends. But I think using structs and pointers is more forward than using object serialization.
In your case, you have 2 structures for each entity I think. A struct which moved along wire or file and a class which holds the entity instance inside memory. If you use binary serialization for your object, you can use just a class for sending, receiving and keeping the instance.
Data modelling
Generally, your C++ classes should factor the redundancy in the data they model. So, if the packets share some common layout, then you can create a class that models that data and the operations on it. You may find it convenient to derive classes that add other data members reflecting the hierarchy of possible packet data layouts, but other times it may be equally convenient to have unrelated classes reflecting the different layouts of parts of the packet (especially if the length or order of parts of the message can vary).
To give a clearer example of the simplest case fitting in with your ideas - if you have a standard packet header containing say a record id, record size in bytes and sequence id, you might reasonably put those fields into a class, and publicly derive a class for each distinct record id. The base class might have member functions to read those values while converting from network byte order to the local byte order, check sequence ids are incrementing as needed etc. - all accessible to derived classes and their users.
Runtime polymorphism
You should be wary of virtual members though - in almost all implementations they will introduce virtual dispatch pointers in your objects that will likely prevent them mirroring the data layout in the network packets. If there's a reason to want run-time polymorphism (and there can easily be, especially when reading packets), you may find it useful to have a polymorphic hierarchy of classes having 1:1 correspondences with the hierarchy of non-polymorphic data-layout classes, and just containing a pointer to the location of the data in memory.
Performance
Using a class or struct with layout deliberately mirroring your network packets potentially lets you operate on that memory in-place and very conveniently, trusting the compiler to create efficient code to do so. Compilers are normally pretty good at that.
The efficiency (speed) of that access should be totally unaffected by the hierarchy of classes you use to model the data. The data offsets involved and calls to non-virtual functions will all be resolved at compile-time.
You may see performance degredation if you introduce virtual functions as they can prevent inlining and require an extra pointer indirection, but you should put that in context by considering how else and how often you'd have switched between the layout-specific operations you need to support (for example, using switch (record_id) all over the place, if (record_id == X), or explicit function pointers).
I have to write a bunch of DTOs (Data Transfer Objects) - their sole purpose is to transfer data between client app(s) and the server app, so they have a bunch of properties, a serialize function and a deserialize function.
When I've seen DTOs they often have getters and setters, but is their any point for these types of class? I did wonder if I'd ever put validation or do calculations in the methods, but I'm thinking probably not as that seems to go beyond the scope of their purpose.
At the server end, the business layer deals with logic, and in the client the DTOs will just be used in view models (and to send data to the server).
Assuming I'm going about all of this correctly, what do people think?
Thanks!
EDIT: AND if so, would their be any issue with putting the get / set implementation in the class definition? Saves repeating everything in the cpp file...
If you have a class whose explicit purpose is just to store it's member variables in one place, you may as well just make them all public.
The object would likely not require destructor (you only need a destructor if you need to cleanup resources, e.g. pointers, but if you're serializing a pointer, you're just asking for trouble). It's probably nice to have some syntax sugars constructors, but nothing really necessary.
If the data is just a Plain Old Data (POD) object for carrying data, then it's a candidate for being a struct (fully public class).
However, depending on your design, you might want to consider adding some behavior, e.g. an .action() method, that knows how to integrate the data it is carrying to your actual Model object; as opposed to having the actual Model integrating those changes itself. In effect, the DTO can be considered part of the Controller (input) instead of part of Model (data).
In any case, in any language, a getter/setter is a sign of poor encapsulation. It is not OOP to have a getter/setter for each instance fields. Objects should be Rich, not Anemic. If you really want an Anemic Object, then skip the getter/setter and go directly to POD full-public struct; there is almost no benefit of using getter/setter over fully public struct, except that it complicates code so it might give you a higher rating if your workplace uses lines of code as a productivity metric.
two clients communicate to each other on top of a message layer
in the message body, I need include a field pointing to any data type
From client A, I send the field as a shared_ptr<TYPEA> to the message layer.
I define this field as a shared_ptr<void> in the message layer.
But how can I convert this field back to shared_ptr<TYPEA> in client B?
Or should I define shared_ptr<void> in message layer as something else?
Thanks
If you're using boost::shared_ptr then you can use the various XXX_ptr_cast<>() functions (static_ptr_cast, dynamic_ptr_cast...).
If you're using the MSVC 2010 version I haven't been able to find an implementation of these functions. They may not be part of the standard.
If the shared_ptrs & pointed-to data aren't held in memory common to both clients (e.g. the clients run in different processes, and the data isn't in shared memory), the pointers from one client won't be valid for the other. You'll need to construct a representation of the pointed-to data and transmit that. The receiver constructs its own copy of the data in the messaging layer and passes a shared_ptr to that up to the client.
If all possible data types that you plan on passing between clients inherit from some common base class, you can simply include a flag variable in the base class which indicates which derived type the current instance is. Pass base-class pointers between clients, and then use dynamic_cast to downcast the base pointer to the appropriate derived type.