GregFreeman Posted July 8, 2013 Report Share Posted July 8, 2013 Sorry, this topic title is awful, but I will explain what I want to do here and look for feedback and suggestions. I have a bunch of different record types, each one has a "format for file" must override method. So my heirarchy looks like this: Record base class, with record children A, B, C, D, E. I have a method to send a record to my logger. I want to be able to send A, B, C to this logger, but I do not want to be able to send D or E. If D or E is used should always be passed into C first. When C writes to a file, it calls D or E's format for file VI. Now, my initial thought was to pull D and E outside this inheritance hierarchy, that way they could not be sent via the "send record" method. But, these classes still need a way to be formatted for a file, so I end up creating another class hierarchy with seemingly duplicate behavior. This may be correct, but I was curious if there is a more straight forward way around this. Quote Link to comment
drjdpowell Posted July 9, 2013 Report Share Posted July 9, 2013 Why are classes D and E not children of C, if they are to use C’s method? 1 Quote Link to comment
GregFreeman Posted July 9, 2013 Author Report Share Posted July 9, 2013 Their own overriden method will be called inside Cs method, but they do not directly use C's method. This may clarify what I'm trying to do. I have an existing structure in C/C++ typedef struct {//edited some stuff out to be more concise for this post union { struct { fat_data_record_TAG id[TSNCHN]; } FAT; struct { fat_data2_record_TAG id[TSNCHN]; } FAT2; struct { gag_record_TAG gi; } GAG; struct { int RecordNumber; int EventCode; int CurrentLoadCondition; int CurrentLoad; int GoingToLoad; char Desc[TSLDES+1]; static_data_record_TAG sd[TSNCHN]; } STA; struct { int RecordNumber; int EventCode; int CurrentLoadCondition; int CurrentLoad; int GoingToLoad; char Desc[TSLDES+1]; char ItemCode[TSNCHN][TSLITM+1]; } RDB; } Data;} SpectrumData_TAG; Unions don't exist in LabVIEW obviously, so I was going to replace the union with a single, DataRecord member, the type of which would be injected. Now, I have classes FAT, FAT2, GAG, STA and RDB, one of which would be injected at run time. The problem is I don't want FAT, FAT2, GAG, STA, or RDB to be sent to my logger alone, they need to be inside the SpectrumData_TAG class. However, because SpectrumData_TAG along with FAT, FAT2, GAG, STA and RDB are all DataRecords, the method to "send new record" will accept them all...there is no protection from a FAT, FAT2 etc from being sent. So, I assumed by breaking up the inheritance heirarchy, I could protect from this. But, then I lose the fact that FAT, FAT2, GAG, STA, and RDB all need to have a method which is defined in the DataRecord base class. So I end up duplicating that. Clear as mud? Quote Link to comment
GregFreeman Posted July 9, 2013 Author Report Share Posted July 9, 2013 (edited) Bit of a brain fart I think... I believe you're right James. I should make these a child class of "C" or SpectrumData_Tag. Just queue up either Fat, Fat2 etc and all the data I edited out would be in the parent class (SpectrumData_Tag), because it pertains to all children types. I think the problem came from forcing the existing structure layout into my OO architecture. But, the problem then becomes, they could queue up SpectrumData_Tag itself, which is relatively meaningless; it needs to have the associated data from Fat, Fat2, GAG, etc. I suppose this isn't that big a deal though. Edited July 9, 2013 by for(imstuck) Quote Link to comment
mje Posted July 9, 2013 Report Share Posted July 9, 2013 However, because SpectrumData_TAG along with FAT, FAT2, GAG, STA and RDB are all DataRecords... I think this may be your problem. I'd tackle it like so: class SpectrumData{ public virtual DoSomething();}// Each type inherits from the SpectrumData classclass FAT : SpectrumData{ // Implement the must-override public DoSomething();}// Other implementations...class FAT2 : SpectrumData;class GAG : SpectrumData;class STA : SpectrumData;class RDB : SpectrumData;// Note no inheritanceclass SpectrumData_TAG{ SpectrumData Data; DoSomething();}SpectrumData_TAG::DoSomething(){ // The TAG class delegates to the appropriate implementation of the contained type. Data.DoSomething();} That is the TAG class wouldn't share the same ancestor as each individual type. I'm assuming there's a good reason you're looking to preserve this union-like behavior. 1 Quote Link to comment
GregFreeman Posted July 9, 2013 Author Report Share Posted July 9, 2013 (edited) That is the TAG class wouldn't share the same ancestor as each individual type. I'm assuming there's a good reason you're looking to preserve this union-like behavior. Thanks, I'll digest that in a minute. The reason for this behavior is because they are logging to a binary file, and we are trying to match that file in our new system so existing parsers will work. Each record defines some common data for the test, but the data in the record itself can only be one type (FAT, GAG, etc). That is the use of the union in this case. I felt that lends itself to injecting the proper data type for a test, into a single member variable at runtime depending on the test type, and scrapping the union. Edited July 9, 2013 by for(imstuck) Quote Link to comment
GregFreeman Posted July 9, 2013 Author Report Share Posted July 9, 2013 After reviewing this, I think it gets me pretty close to what I want but not exactly. This is because there are other "Tag" structures/classes that need to be written to a file, also. The DoSomething method is flattening these particular classes to be written to a binary file. I am almost feeling that I need interfaces, so I can have the "FileWritable" interface, with a method FlattenToFileData() which would allow me to separate the inheritance heirarchies but still enforce this method. For the time being, I have broken out the inheritance heirarchies as you suggested (Tag separate from data), and in each one have put a must override, FlattenToFileData() method. It's a bit redundant but will do what I want. Quote Link to comment
Daklu Posted July 20, 2013 Report Share Posted July 20, 2013 Maybe my browser isn't rendering correctly but the only thing I could think of was, "uhh... not really." Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.