This question is likely a "what does the C++ standard say" thing, but my Google searching hasn't given me the answer I'm looking for.
I know that when you have classes, and you have one class inherit from another class, you get into the world of virtual function tables, since the code needs to figure out which class contains the function you're trying to call.
But what about inheritance between structs that only contain data? For example, if you have a widget struct, and then you want a specialized version of that struct that has a few extra variables, but you still want to be able to pass its original data to functions that handle widgets, it would be simpler to inherit from the original widget struct than to make your code handle two types of widget structs. Is there any overhead when there is only data involved in the inheritance? Is the specialized widget still a simple struct (in terms of memory layout) with both data combined, or is the original widget data stored separate from the new data?
Ultimately, I'd like to keep my data simple and contiguous, as a basic struct would be, and I don't know if inheriting data would break that.
In the C++ memory model an object is always laid out in contiguous memory. You need to use members pointing to data outside this object if you want to have non-contiguous memory. That is, if you inherit any class whether it is a struct or has virtual function, the actual object is always contiguous. There are few other implications about types which may be of interested: if a class is a standard layout type you can e.g. memcpy() the object. I'm not sure what C++2011 says about inheritance and standard layout type but I'm pretty sure that C++2003 didn't allow inheritance and C++2011 allows it.
know that when you have classes, and you have one class inherit from another class, you get into the world of virtual function tables
only if you have virtual functions...
so to answer your question: if you have a plain struct without member functions, then the compiler won't generate a virtual function table.
and BTW you shouldn't be worrying about it, that table is per class, and you only need a simple extra pointer per instance (if you use simple inheritance).
Related
I have a base class and two derived classes. I want to write and read objects of these classes to / from a file. I was thinking about virtual functions to write/read data, but I don't know where should I place these functions. In the base class? When I will be reading data from the file I will store pointers to objects in a vector, but I suppose I cannot have a vector of pointers to objects of a class in which this vector is declared. Could someone help me solve this problem? Thanks in advance for any advice.
When you write the objects to the file, you also have to store some information such that you know the type/class of the object when reading it in again later; Otherwise you will not know which of the derived classes to instantiate.
Once you have solved this, you can decide to store the objects where ever and in which way you want.
As far as I understand your problem, you have a base class and two derived classes. All of them you want to write and read from a file and you want to read more than one instance from this object at a time.
In my opinion you need a container class, which takes care of the reading and writing. This means you implement a class, which stores your instances in a vector and then can save them to the disk and read them again.
Saving different types of classes, which are inherited from the same base class, requires additionally that you add a type, which you have to check during the writing and the reading, to process the stored information correctly.
I am not fully versed in C++ and with the current project I am working on, have hit a small snag. I have come across this: http://www.terrainformatica.com/2010/08/cpp-how-to-change-class-of-object-in-runtime/ but I am unsure if this is the solution I am looking for or if there are any better alternatives.
My intentions is to switch turret types stored in memory, despite them being different instantiations of base CTurret. And with as little performance impact as possible since this is going to be implemented in a simple game.
Basically I have a base class CTurret of base class CEntity. Now I have several Turrets (Basic, Fast, Harmless). Each turret uses the base class CTurret I want to reserve some memory to hold generic turrets which can then be simply swapped out for an actual turret type. Better visual below:
class CEntity...
class CTurret : public CEntity...
class CBasicTurret : public CTurret...
class CFastTurret : public CTurret...
Memory (5 generic turrets)
Array[CTurret, CTurret, CTurret, CTurret, CTurret] // Can not use generic!
User wants a basic turret, populate an available generic turret:
Array[CBasicTurret, CTurret, CTurret, CTurret, CTurret] // Ah, a basic turret I'll use that.
When no longer needed:
Array[CTurret, CTurret, CTurret, CTurret, CTurret] // Back to original.
So far I can see only two options to achieve what I want:
1) I could put all the turret types in the basic class and change it form the base to... an actual class. But this would get messy fast.
2) I could reserve memory for each turret type which would not be an ideal situation since memory is precious and should not be wasted as such. Also the user may request more than is already reserve which could pose future problems.
You need to decide what the difference is between turret types.
The general choices are a polymorphic base class (with the derived classes overriding inherited virtual functions to specialise behaviour) or a single class with state (e.g. an enumerated type to describe operating modes, a float to describe speed, etc).
An array of smart pointers can be used if you decide on a polymorphic base. Simply pick which pointer (or index into the array) to use. The pointers (and objects they point to) will be in memory anyway.
With a single object, just change its state as required. So change values like height, width, operating mode, etc. This is the better option if you're really worried about memory usage (only one object in memory needed, although there is nothing stopping you having an array of objects, where each element has different state).
The placement new trick you linked to has a few gotchas that have been glossed over, and the particular example of morphing an object with data into an object that doesn't is problematical (e.g. causing the caller to exhibit undefined behaviour).
Say I have an Image class which performs manipulation on an image file, such as make the image black and white, gray-scale, etc. The image bytes are stored in an attribute which is an array. Now I want other programmers to add functionality to the Image class if they like to. I assume that this is done by creating their own class which inherits from Image. Examples of functionality that they could add would be rotate image, crop image, etc.
My question is what should I do in this case to allow other programmers to add functionality to the Image class, should I make the array that holds the image bytes protected, which will allow only child classes to modify it directly?
Using protected attribute on the array and a public inheritance access specifier is best. This allows subclasses to keep the same public interface without having to expose too much implementation detail, and still allows the subclass the ability to modify the array.
Just as you suggested, that's what the access specifiers are for.
http://www.cplusplus.com/doc/tutorial/inheritance/
http://en.wikibooks.org/wiki/C++_Programming/Classes/Inheritance
The first thing is to consider whether there are any invariants that your class needs to maintain - for example, that the image member's dimensions aren't change by a derived class because separate x/y data members in the base class could get out of sync, or that a pointer to the data is not re-seated by the derived class because some other private member stores pointers into the data to track say brightest-pixel locations or whatever. So, there's a process of deciding what kind of functionality belongs exclusively in your class, and what access you can grant to derived classes without it being easy to break your functionality. You may still have to "trust" derived classes not to do weird things, but you should try to make it hard to do accidentally, and document your base class well. If you want to learn about this kind of thing, you might reasonably start with the Liskov Substitution Principle.
I'm very new to C++ and am trying to find a good pattern for having the following:
A base class that defines several (virtual?) functions and properties.
Several varying classes that inherit from this base class and override some or all of the virtual functions and work with the parent's properties.
Then my plan was to have a single variable that can store any one of the classes and call functions defined in the base one. Sometimes I will swap out the object in this variable for one of the others.
Does this seem sensible and how can I store objects like this of varying classes? I was hoping to just be able to define the variable as BaseClass myCurrentObject; and then do something like myCurrentObject = ChildClassA(); or myCurrentObject = ChildClassB(); etc but it doesn't seem to be that simple!
What you describe is exactly polymorphism, so yes, this is reasonable.
As proposed in the comments, you have to use pointers for referencing to the objects, as in
BaseClass* obj = new ChildClassA();
obj->call_some_virtual_function();
// ^ Will call the most derived definition of the function
Of course, if you are writing any serious program, you should not use plain pointers here. They simply make it too likely that you will sooner or latter forget to delete the old object pointed to by obj before assigning a new one to it. But since you said you are new to C++ and might just want to try things out, the above could fine.
The reason why it cannot be as easy as simply writing BaseClass obj = ChildClassA(); is that this defines obj to be an object of type BaseClass. But since ChildClassA might have more members than BaseClass, you cannot store a ChildClassA at a spot that was only intended for a BaseClass object. You should thus realize that polymorphism requires a variable amount of memory, and this you can only get on the heap.
I want to create an instance of a class and place it in shared memory so the same instance can be called from multiple processes. However, this class has virtual methods which I think may cause problems as I have read the mapped data can't contain pointers, which would be the case here with the vtable in the class. Will it work?
As Kerrek SB commented, you cannot map a class containing virtual methods. But you can probably make a simple struct or class without virtuals, map that, and then give a pointer to it to another class which does have virtuals and uses the plain struct as its implementation. Basically, the Pimpl idiom.
If needed, you can even do something like virtual dispatch yourself by storing a "type" integer in the plain struct, and inspecting it to decide which functions to invoke.