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.
Related
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 have a vector with pointers to a base class object so i can manage objects derived from that class.
vector <Product*> products;
i am trying to write these objects to a file while iterating through the vector
but i am not sure if this works correctly.
void Inventory :: saveProductsToFile()
{
ofstream outfile;
outfile.open("inventory.dat",ios::binary);
list <Product*> :: iterator it;
for(it=products.begin(); it!=products.end(); it++)
outfile.write((char*)*(it),sizeof(Product));
}
The file is created but i have no idea if i'm saving the actual objects themselves or their
addresses.Is this correct or is there another way?
This is how the file looks like:
ˆFG " H*c \Âõ(œ##pFG h*c b'v b#
You code can work. You cannot serialize polymorphic objects in
that way. For starters, you're writing the hidden vptr out
to disk; when you reread the data, it will not be valid. And
you're only writing out the data in the base class (Product),
because that's what sizeof(Product) evaluates to. And
finally, just writing a byte image of anything but a char[]
will probably mean that you won't be able to reread the data
some time in the future (after a compiler upgrade, or a machine
upgrade, or whatever).
What you have to do is to define a format (binary or text) for
the file, and write that. For the basic types, you can start
with something existing, like XDR or Protocol buffers, but
neither of these work that well with polymorphic types. For
polymorphic types, you have to start by defining how you
identify the type in question when rereading. This can be
tricky: there's nothing in std::type_info which helps, so you
need some means of establishing a relationship between your
(derived) types and the identifier. Then every derived class
must implement a write function, which first writes its type,
then writes its data out, one element by one. When reading, you
read the type, look up the appropriate read function for that
type in a map, and call that function, which then reads the data
one by one.
Finally, I might point out that all successful serialization
schemes I've seen depend on generated code. You describe your
types in a separate file, or in special markup (in a specially
marked comment in the C++), and have a program which reads that,
and generates the necessary code (and often the actual classes
you use).
Thats not how you "serialize" data. Like this the pointers are only valid during runtime or until you delete them (depending on what happens/stops first). Like this you wouldn't be able to restore your data, because after the program has stopped everything from your former memory becomes invalid. You would have to store the actual values from your class.
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 a C++ objects that looks like this
class myClass
{
vector<OtherClass*> otherClassVector;
AnotherClass* anotherClassObj;
// A few other primitive types and functions
}
What is the best way to store this to disk and read it back programmatically?
Will using fstream read/write in binary mode work? Or should I use boost serialization? And why?
I don't require the stored file to be human readable.
Using boost::serialization is simply, than write your own serializer. If OtherClass is concrete type (not base) - serialize by read/write is simple, for vector - just save size and than array (if your myClass has no non-POD types) and then store element on which points anotheClassObj pointer...
You can serialize objects with ofstream f("filename", std::ios::binary); only if those objects are POD-types.
Anything else needs to be handled manually. For a simple example, if the object contains any pointers, the addresses of those will be saved, not the data they point at.
For more complex types, you will have to either serialize them completely manually (write a class or function that will save all the POD data from the class and do something tricky with all the "special" data)), or use boost serialization.
The C++_Middleware Writer may be of interest. It has some advantages over other approaches.
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).