Data Structure with inheritance. Problems initializing - c++

I need make a class, let's say FineStack, who should declare a structure able to manage different kind of Fines ( LightFine, SeriousFine ). The superclass for both is Fine.
The question is, do I really need templates? I thought it was not necessary, so this is what I thought:
-> declare Fine *fines; ( kind-of array of fines? ) And ... creating an array of Fine's objects (the superclass), it should be able to manage both LightFine and SeriousFine objects.
-> The problem is. How should I declare it? Fine should be an abstract class, so no instances could be created (instances should be either LightFine's or SeriousFine's ).
I got stuck with this, since I don't find the way to get it. I've read in multiple questions here in Stackoverflow, that you guys usually suggest to use std::vector , which makes you easier to manage this kind of stuff.
Should I go in that way and forget about the original idea?
I need a structure which should be able to handle any object from both subclasses, in any order (let's say .. 3 LightFine and 2 SeriousFine ... or alternatively each other from the start to the end of the structure ... whatever.

I would like to point you in the right direction and not just give you the whole shebang. If this doesn't help, please ask about what's troubling you:
Although Fine cannot be instantiated, you can point to it, so:
Fine* f1 = new LightFine();
Fine* f2 = new SeriousFine();
are both legal, because LightFine is-a Fine and SeriousFine is-a Fine.
Edit: I see this is not clear yet. If you read the above you can see that I can hold a pointer Fine*, yet have it "secretly" point to either LightFine or SeriousFine. That means, If I were to keep a bunch of Fine* pointers, some of them could be LightFine and some SeriousFine. i.e, I can do this:
Fine** fines = new Fine*[5];
f[0] = new LightFine();
f[1] = new SeriousFine();
...
for (int i=0; i<5; i++) {
std::cout << fines[i]->toString() << std::endl;
}
and the output would be:
a light fine
a serious fine
...
if you do want to use a vector, it too should be of type vector<Fine*> and not vector<Fine>.

You can't have an array of Fines or a vector of fines because the Fine class is abstract (and it should really be).
The solution is to use either an array of pointers (like Fine **fines and fines = new Fine*[whatever-size-you-need]) or a vector of pointers (like std::vector<Fine*> fines). After that, you can instantiate any subclass of Fine with new and it will be implicitly upcasted to Fine* when you put it into the array/vector.
And you certainly don't need templates here, unless you have another (unrelated) reason to use them.

In C++, polymorphism (the ability to have the same code work with objects of multiple different subclasses of a given parent class) is accomplished with pointers and references to base classes, not base class types themselves. If you come from a language like Java this might be confusing, because there all object references implicitly behave like pointers do in C++.
Ideally you should use vector<std::tr1::shared_ptr<Fine> >. The Boost documentation does a good job explaining why shared_ptr simplifies memory management; TR1's shared_ptr is essentially the same as Boost's except that it probably already comes with your compiler.
If you're content to do your own memory management, use vector<Fine*>. Don't use vector<Fine> -- that will cause object slicing.
What is object slicing? LightFine is (possibly) bigger than Fine, so it won't fit in the same amount of memory. If you declared Fine a; LightFine b; a = b; this will compile, but the entire LightFine object won't fit in a, so just the Fine subobject of b will be copied. Essentially the same thing happens when inserting a LightFine object into a vector<Fine>.
You won't be able to treat a as a LightFine object after that assignment, since its static type is just Fine, and all the LightFine "parts" have been discarded anyway. Also, treating a as a Fine object can produce unexpected behaviour -- for example Fine might have an internal data field that is repurposed by LightFine and thus contains an out-of-bounds value when interpreted by Fine's methods.

Revised answer after my first had errors:
Will both LightFine and SeriousFine implement only the interface from Fine, or will they have additional methods that the FineStack will need to know about?
If the FineStack will only interact with the Fine objects using methods defined in Fine's interface, then I don't see a problem with your array approach, as long as you use Fine** fines (i.e. an array of pointers to Fines). Although, I'd tend to use a std::vector<Fine*> instead.
(I did have a comment here about dynamic_cast, but I've removed it after a couple of commentors suggested it was dangerous advice).

sounds like you should go with std::vector<Fine>

Related

C++ subtype degeneration when placed in a container

I am currently taking a course in c++, coming from a java background.
We've now gotten to the point where we talk about inheritance. This week's class didn't really explain what was needed to do the weekly assignments, leaving me somewhat at loss trying to solve them.
While I will be getting around to asking my tutor himself, that'd mean waiting until next week, putting me behind.
Allow me to demonstrate what I want to do:
class base
{
int field1;
base(int _field):
field1(_field){}
};
class subclass : public base
{
int field2;
public:
subclass(int _field2):
base(_field1),field2(_field2){}
string to_string()
{
return "I am a subtype!!";
}
};
int main()
{
vector<base> x;
x.push_back(subclass(123,456));
cout<<x[0].to_string[]<<end; //error!!
}
To my surprise, this code won't work, it won't even compile. The container x will cast the objects within it to the basetype, this means I am forced to treat what was once subtypes, as basetypes, which means that the subtypes variables and functions are out of reach.
What I want to do, is to treat the objects within the container as subtypes, IE typetesting(in itself a non-trivial matter) them and then do different things depending on what type the objects are.
This was trivial in java. There I could simply fill, say, an array of type base with subtypes and then go about doing whatever I wanted with the objects within.
I am assuming what I did in java, is supposed to be possible in C++, being able to place subtypes into some sort of container and then treat them as subtypes ought to be possible. It is evident I have missunderstood something fundamental here, this problem was entirely unforeseen to me.
It is worth mentioning that I tried this with both vector, and simple arrays. Exact same pattern emerged, the type of the array dictates how I can access the objects, ie I can't call to_string().
So to summarize: I wish to know how I can contain subtypes in containers without having my container casting the objects inside to the container's type.
This was trivial in Java. There I could simply fill, say, an array of type base with subtypes and then go about doing whatever I wanted with the objects within.
The main difference between objects in Java and in C++ is that all Java objects are accessed through a reference (somewhat similar to C++ smart pointers) while in C++ you have an option of accessing objects directly. This works fine and saves a lot of memory and some CPU cycles with non-polymorphic objects, but breaks spectacularly once inheritance enters the stage due to object slicing.
It's a problem of putting ten pounds of stuff into a five-pound bag: vector<base> allocates enough space to fit N items of type base, so when you try to put subclass into the same space, the compiler tells you that it is not going to fit.
To work around this issue, emulate what Java does, i.e. use smart pointers:
vector<unique_ptr<base> > x;
unique_ptr<base> item(new subclass(123,456));
x.push_back(std::move(item));
Demo.
Note: There are several issues in your code that you need to fix in order to make this work. First, add a public to_string member function to base. Then, replace the call of to_string through the dot . operator with a call through the arrow -> operator. Finally, fix a few typos - the square brackets in the call of to_string, and a missing l in endl.

data inheritance in C++

I have two class, one for storing base data, and the other for storing additional data as following:
struct AnimationState(){
virtual ~ AnimationState(){};
Vector3f m_spacialData;
float m_fTimeStamp;
}
And the derived class:
struct HermiteAnimationState() : public AnimationState{
virtual ~HermiteAnimationState(){};
Vector3f m_tangentIn;
Vector3f m_tangentOut;
}
My question: is how can I, at first, create an instance of HermiteAnimationState, and then upcast it to AnimationState for storing in a vector like this:
std::vector<AnimationState> m_vStates;
...
Lately, I can get the object AnimationState and downcast it to HermiteAnimationState for accessing the additional data (member m_tangentIn and m_tangentOut).
HermiteAnimationState* p = dynamic_cast<HermiteAnimationState*>(&m_vStates[i])
The way polymorphism works in C++ is that if B is a base class and D is derived from B, then:
a pointer to D can be used where a pointer to B is expected
a reference to D can be used where a reference to B is expected
What you can't do in C++ is actually use a value of type D in a context where a value of type B is expected. For example, you can't store derived objects in an array of base object. This makes sense when you consider that a derived object may have a different size from a base object.
Similarly, you can't store derived objects in a vector of base objects.
What you can do is store pointers to HermiteAnimationState in a vector of pointers to AnimationState. It's up to you how to manage the memory. For example, the following would be valid:
std::vector<AnimationState*> m_vStates;
HermiteAnimationState h_a_s;
m_vStates.push_back(&h_a_s);
...
HermiteAnimationState* p = dynamic_cast<HermiteAnimationState*>(m_vStates[i])
Since h_a_s is a local variable, it'll be destroyed automatically at the end of its scope.
But this is probably an unworkable approach, because you probably want the objects referred to by the vector elements to persist beyond the current scope. We can use std::unique_ptr for this purpose. A std::unique_ptr owns the object it points to, and as long as it stays alive, so does that object; and it deletes the object when it is itself destroyed. So a vector of std::unique_ptr objects behaves like a vector of objects themselves in terms of memory management. Now you can do
std::vector<std::unique_ptr<AnimationState*>> m_vStates;
m_vStates.emplace_back(new HermiteAnimationState);
...
HermiteAnimationState* p =
dynamic_cast<HermiteAnimationState*>(m_vStates[i].get());
(Note, however, that you can't copy this vector; you can only move it.)
Basically, you need to use some kind of reference to the pointed object because you need dynamic polymorphism.
The simplest but error-prone would be using "naked" pointers. The first thing that is problematic with this is that you have to do the destroying manually: containers will destroy the pointer, not what is pointed.
The safer way to do this is to use smart pointers, which are designed to do the destruction depending on a pre-fixed rule that the smart pointer embedd in it's type. The simplest one and certainly the best choice if you are doubting is std::unique_ptr, which can't be copied but can be moved. The other choice, which should be thought carefully about before being used, is the std::shared_ptr which is useful IFF you don't know when you should destroy these objects but you know it's when some systems will refer no more to it. Some other systems might just be observing that object, in which case std::weak_ptr.
Now, from reading your question, I think you are certainly processing a lot of these animation data. There is an obvious design issue there, I think, I might be wrong.
However, it looks like, if you have a lot of these AnimationState to manage, in a loop, you will get performance issues. This is common issues in games, mainly caused by "cache conherency".
What I would recommand in this case, would be to NOT use
inheritance: it's an invitation to the cpu to jump all over the place and trigger cache misses;
dynamic_cast: it's one of the few operations that are not guaranteed to end in a predictable time (with new and delete for example), which basically mean that if you are in a critical loop, you can lose a lot of time through it. In some cases, you can't avoid using dynamic cast (like when doing dynamic plugins), but in most cases, using it just because you have chosen to use inheritance is just wrong. If you use inheritance, then you should use virtual calls.
However, what I suggest is even more drastic: don't use inheritance at all.
Obviously, this is only an advice. If you are not doing something with a critical loop, it doesn't matter. I'm just worried because it looks like you are doing some inheritance for composition, which always have bad consequences both on readability of the code and performance.

How to store class member objects in C++

I am trying to write a simple game using C++ and SDL. My question is, what is the best practice to store class member variables.
MyObject obj;
MyObject* obj;
I read a lot about eliminating pointers as much as possible in similar questions, but I remember that few years back in some books I read they used it a lot (for all non trivial objects) . Another thing is that SDL returns pointers in many of its functions and therefor I would have to use "*" a lot when working with SDL objects.
Also am I right when I think the only way to initialize the first one using other than default constructor is through initializer list?
Generally, using value members is preferred over pointer members. However, there are some exceptions, e.g. (this list is probably incomplete and only contains reason I could come up with immediately):
When the members are huge (use sizeof(MyObject) to find out), the difference often doesn't matter for the access and stack size may be a concern.
When the objects come from another source, e.g., when there are factory function creating pointers, there is often no alternative to store the objects.
If the dynamic type of the object isn't known, using a pointer is generally the only alternative. However, this shouldn't be as common as it often is.
When there are more complicated relations than direct owner, e.g., if an object is shared between different objects, using a pointer is the most reasonable approach.
In all of these case you wouldn't use a pointer directly but rather a suitable smart pointer. For example, for 1. you might want to use a std::unique_ptr<MyObject> and for 4. a std::shared_ptr<MyObject> is the best alternative. For 2. you might need to use one of these smart pointer templates combined with a suitable deleter function to deal with the appropriate clean-up (e.g. for a FILE* obtained from fopen() you'd use fclose() as a deleter function; of course, this is a made up example as in C++ you would use I/O streams anyway).
In general, I normally initialize my objects entirely in the member initializer list, independent on how the members are represented exactly. However, yes, if you member objects require constructor arguments, these need to be passed from a member initializer list.
First I would like to say that I completely agree with Dietmar Kühl and Mats Petersson answer. However, you have also to take on account that SDL is a pure C library where the majority of the API functions expect C pointers of structs that can own big chunks of data. So you should not allocate them on stack (you shoud use new operator to allocate them on the heap). Furthermore, because C language does not contain smart pointers, you need to use std::unique_ptr::get() to recover the C pointer that std::unique_ptr owns before sending it to SDL API functions. This can be quite dangerous because you have to make sure that the std::unique_ptr does not get out of scope while SDL is using the C pointer (similar problem with std::share_ptr). Otherwise you will get seg fault because std::unique_ptr will delete the C pointer while SDL is using it.
Whenever you need to call pure C libraries inside a C++ program, I recommend the use of RAII. The main idea is that you create a small wrapper class that owns the C pointer and also calls the SDL API functions for you. Then you use the class destructor to delete all your C pointers.
Example:
class SDLAudioWrap {
public:
SDLAudioWrap() { // constructor
// allocate SDL_AudioSpec
}
~SDLAudioWrap() { // destructor
// free SDL_AudioSpec
}
// here you wrap all SDL API functions that involve
// SDL_AudioSpec and that you will use in your program
// It is quite simple
void SDL_do_some_stuff() {
SDL_do_some_stuff(ptr); // original C function
// SDL_do_some_stuff(SDL_AudioSpec* ptr)
}
private:
SDL_AudioSpec* ptr;
}
Now your program is exception safe and you don't have the possible issue of having smart pointers deleting your C pointer while SDL is using it.
UPDATE 1: I forget to mention that because SDL is a C library, you will need a custom deleter class in order to proper manage their C structs using smart pointers.
Concrete example: GSL GNU scientific library. Integration routine requires the allocation of a struct called "gsl_integration_workspace". In this case, you can use the following code to ensure that your code is exception safe
auto deleter= [](gsl_integration_workspace* ptr) {
gsl_integration_workspace_free(ptr);
};
std::unique_ptr<gsl_integration_workspace, decltype(deleter)> ptr4 (
gsl_integration_workspace_alloc (2000), deleter);
Another reason why I prefer wrapper classes
In case of initialization, it depends on what the options are, but yes, a common way is to use an initializer list.
The "don't use pointers unless you have to" is good advice in general. Of course, there are times when you have to - for example when an object is being returned by an API!
Also, using new will waste quite a bit of memory and CPU-time if MyObject is small. Each object created with new has an overhead of around 16-48 bytes in a typical modern OS, so if your object is only a couple of simple types, then you may well have more overhead than actual storage. In a largeer application, this can easily add up to a huge amount. And of course, a call to new or delete will most likely take some hundreds or thousands of cycles (above and beyond the time used in the constructor). So, you end up with code that runs slower and takes more memory - and of course, there's always some risk that you mess up and have memory leaks, causing your program to potentially crash due to out of memory, when it's not REALLY out of memory.
And as that famous "Murphy's law states", these things just have to happen at the worst possible and most annoying times - when you have just done some really good work, or when you've just succeeded at a level in a game, or something. So avoiding those risks whenever possible is definitely a good idea.
Well, creating the object is a lot better than using pointers because it's less error prone. Your code doesn't describe it well.
MyObj* foo;
foo = new MyObj;
foo->CanDoStuff(stuff);
//Later when foo is not needed
delete foo;
The other way is
MyObj foo;
foo.CanDoStuff(stuff);
less memory management but really it's up to you.
As the previous answers claimed the "don't use pointers unless you have to" is a good advise for general programming but then there are many issues that could finally make you select the pointers choice. Furthermore, in you initial question you are not considering the option of using references. So you can face three types of variable members in a class:
MyObject obj;
MyObject* obj;
MyObject& obj;
I use to always consider the reference option rather than the pointer one because you don't need to take care about if the pointer is NULL or not.
Also, as Dietmar Kühl pointed, a good reason for selecting pointers is:
If the dynamic type of the object isn't known, using a pointer is
generally the only alternative. However, this shouldn't be as common
as it often is.
I think this point is of particular importance when you are working on a big project. If you have many own classes, arranged in many source files and you use them in many parts of your code you will come up with long compilation times. If you use normal class instances (instead of pointers or references) a simple change in one of the header file of your classes will infer in the recompilation of all the classes that include this modified class. One possible solution for this issue is to use the concept of Forward declaration, which make use of pointers or references (you can find more info here).

How to construct dynamic number of classes with const members?

So after working on my last question, I boiled it down to this:
I need to add an unknown number user-defined classes (object_c) to a boost::intrusive::list. The classes have const members in them. All I need to do to push them to the list is to construct them and then have them persist, they automatically add themselves.
The code in question is basically
for (unsigned i = 0; i < json_objects.count(); ++i) {
ctor_data = read(json_objects[i]);
// construct object here
}
What I've tried:
mallocing an array of objects, then filling them in: Doesn't work, because I have const members.
static object_c *json_input = (object_c*) malloc(json_objects.size() * sizeof(object_c));
...
json_input[i](ctor_data); //error: no match for call to (object_c) (ctor_data&)
Making a pointer: This doesn't work, functions don't work properly with it, and it doesn't get destructed
new object_c(ctor_data);
Pushing the object back to an std::vector: This doesn't work, boost rants for dozens of lines when I try (output here)
vector_of_objects.push_back(object_c(ctor_data));
Just declaring the darn thing: Obviously doesn't work, goes out of scope immediately (dur)
object_c(ctor_data);
I'm sure there is an easy way to do this. Anyone have any ideas? I've been at this problem for most of the weekend.
#3 should be the method you need to use. You need to elabourate on what your errors are.
If it is just operator= as you show in your previous question, and you dont want to define one, you can try emplace_back as long as you are in C++11. Of Course I am talking std::vector, I need to check what is the equivalent if any in boost::intrusive. Edit: I might be wrong, but it doesnt seem to support move semantics yet..
Alternatively use #2 with smart pointers.
If you are going with #1, you would need to use placement new as #rasmus indicates.
At the end of the documentation's usage section it tells you that
“The lifetime of a stored object is not bound to or managed by the container”
So you need to somehow manage the objects’ lifetime.
One way is to have them in a std::vector, as in the documentation’s final example.
Sorry for the late reply, exam studying and all that.
It was simpler than I was making it out to be, basically. Also, for this answer, I'm referring to my class as entity_c, so that an object of entity_c actually makes sense.
What I was doing in my OP was when I push_back'd an entity_c, it was automatically adding itself to a global intrusive::list, and somehow that made it not work. After I stopped being lazy, I wrote up a minimal compilable progam and played around with that. I found out that making an std::vector to store the constructed entity_cs in worked (even though it deconstructs them when they're added? I dunno what that's about). Then all I had to do was populate a local intrusive::list with those objects, then clone the local list into the global list.
Thanks for all the help, I'll tweak that program to try and fit in different stuff, like placement new suggested by #rasmus (thanks for that, hadn't seen that before). Also thanks to #karathik for showing my emplace_new, I think I might have to go and find out about all these new C++11 features that have been added in, there are so many cool ones. I even learnt how to make my own copy constructor.
Truly and edifying educational experience.

double pointers to C++ objects

I need to modify a really long program that was written by another programmer. Going through his code, you can see double pointers to C++ objects. I don't understand why double pointers are used in this case, I think a single pointer would do the same thing. An example makes it more clear:
class A {
...
public:
static B** b; //why double pointers here?
...
}
Class B {
...
public:
B(...)
func1();
func2();
}
We need to have a number of objects from B class, let say 5 objects (not a 2D array of objects). Once we create b, the code never tampers with *b. Only B's functions are called by b[i]->func1(). So, since we don't change pointers, I would guess we could do the same thing by defining static B* b;. Am I neglecting something?
Maybe the programmer needed an array of objects of type B or deriving from B (or simply not prevent that capability in future programs)? Because the objects deriving from B can be of different size, you cannot simply put them one after another in an array - hence the additional level of reference.
In C++, if you are using boost library, this behavior can be relatively cleanly achieved by boost::ptr_vector or boost::ptr_array which will hide the uglyness of double pointers and prevent you from doing other accidental errors.
If you want a dynamic (raw) array of (raw) pointers, then you'll indeed need a pointer-to-pointer.
Of course, the C++ way would be a vector of smart pointers, or something similar.
It's difficult to say anything more without seeing the complete context.
On older versions of the Mac OS, these were called handles. They were used so the operating system could re-arrange memory without breaking pointers. (That is, the OS can move your objects around and change the pointers to them, as long as you only keep a pointer to the pointer.)
It's hard to know what's going on in your case, but you might want to check to see if some sort of similar memory optimization is going on.
If it was a single pointer then, you're right, it would be a list of pointers to instances of B objects.
The fact that there are double pointers doesn't necessarily mean he was trying to create a 2D array of B objects. Maybe he was trying to make the list of B objects not a list of B objects but a rather a list of references to B objects (e.g. pointers to B objects).
Maybe in the context of your application storing pointers to B objects rather than the objects themselves sounds like a good idea?
Anyway, like I said, double pointers doesn't always mean double lists.
A pointer to something is used to tell code where to find that something or where to put that something. So a pointer to a pointer is used when you need to tell code where to find a pointer or where to put a pointer.