Alright, I am writing some code that will be reading some older files written by a DOS program years ago. The files I will be reading can be considered archives since they contain multiple pieces of data. However, each file will reference the pieces of data either by a DOS file name (char) or a 32bit integer ID (int32_t). This is specified the file file's header.
Now I am trying to simplify use of the class that I am writing by using one pointer that will get allocated either as an array of file name records or an array of numeric ID records. This much is easy. Reading data with fstream is not.
Is what I am trying to do possible, or am I going to have to write double code for every place this is referenced and have two pointers, one being NULL and one pointing to allocated data based on the file type?
If you're comfortable with inheritance and polymorphism, you can have specialised subclasses of File, one for each type of file. These subclasses can override the File::Read method to read the appropriate record type. If you make the Read method virtual, then polymorphism does the rest for you.
1) Use polymorphism virtualvoid read(istream &in); (you need to change to std::vector<smart_ptr<tag> > records;)
a) Cast tagFilenameStruct *q = reinterpreter_cast<tagFilenameStruct*>(pRecords);
> just call the appropriate method once you know the file type
that logic could be stored in the object so you don't screw the calls.
You simply call `read()' and it would automagically determinate which one needs to work with.
I was looking at switching from structures to classes to solve this and it looks as though that may be the best method. I also wanted to switch to vectors, as was suggested above. I will start on both of those today.
Now I am not sure that I want to derive the classes from "File" because I will be reading and writing these at some point. I will have to consider this and weigh my options. Besides, reading isn't my issue. My issue is me preferring not to have two separate pointers, one to each type of structure, or to have a single structure with both types of data in it. It looks like I may have to however.
Oh and the single equal sign is a typo on my part. In the code I actually have two equal signs.
I was looking at switching from structures to classes to solve this and it looks as though that may be the best method.
FYI, classes and structs are almost exactly the same thing in C++. The only difference is that the default access specifier for a struct is public, and for a class it's private.
Having said that, the convention is to use a class when you're encapsulating the data and implementation details behind an interface, and a struct when you're just using it to package together some data items (as you would in C).
Now I am not sure that I want to derive the classes from "File" because I will be reading and writing these at some point.
Why would that stop you? The point is that each specialised class can override the read and write methods from the base class, to read and write the appropriate record types. As long as the methods are declared as virtual in the base class, then you can use polymorphism to automagically call the correct method for the correct file type.
That's not the only way of doing it. You know your class design better than we do, of course, so there may be a more sensible class to derive from. But it's the same principle - use inheritance and polymorphism to avoid having tons of "if... else..." statements.
I decided to combine both into one struct and use that struct in a vector. I then only have one set of if/else statements in the loading code. I don't like wasting the 14bytes per record for the numeric data archives, but that isn't much. Now I get to derive a few specialized cases from the base class.