Help me find the best class design for following problem

Discussion in 'C++' started by Peter, Nov 5, 2011.

  1. Peter

    Peter Guest

    Hi,

    I have following situation that I'm trying to find the best class design
    for:

    Base class: Device
    Two classes inherit from this Device class, let's call them DeviceA and
    DeviceB.

    Both Device classes A and B can also be emulated via a file on the HD
    instead of actually talking to the device.

    However these files come in many flavours. Many are unique to the type of
    device, yet some are possible for the two types of devices.
    So in one case file X is for device A, but in another it's for device B

    So I was first thinking of a template where I inherit from the template
    class

    template <class T>
    class FileDevice : public T

    And in this class I put the huge shared code base of the two types possible

    Then I create file-type specific classes that inherit from either
    FileDevice<DeviceA> or FileDevice<DeviceB>
    And for the file type classes that cover both devices I probably best also
    make them similar templates and instanciate objects either using
    FileDevice<DeviceA> or FileDevice<DeviceB> as base class.

    How do you feel about this ?

    But then I run into following issues:

    In the GUI part of the code there are several places where it makes sense to
    see if I'm using a file or an actual device, for display and other user
    interface purposes (e.g. loading/unloading a file etc.).
    There I would normally test the Device pointer via a dynamic cast. If
    (dynamic_cast<FileDevice*>(DevicePtr)) { do stuff ; }
    However with a template design this doesn't work, as FileDevice needs a
    template class.

    Fact of the matter is that both DeviceA and DeviceB are Device classes but
    testing this: If (dynamic_cast<FileDevice<Device>*>(DevicePtr)) { do stuff
    ; }
    won't work I assume ?

    So how would you do this ?

    So I was also thinking of multiple inheritance. Something I've never done
    in my code but anyway:

    class FileAccess {}

    template <class T>
    class FileDevice : public T, FileAccess

    Doing this I would be able to test:
    If (dynamic_cast<FileAccess*>(DevicePtr)) { do stuff ; }
    *I assume* ?

    However there are other problems then as well, since FileAcces is NOT A
    Device class I can't pass this pointer to functions that expect a Device
    pointer, while in fact the FileAccess device in use IS in reality a Device
    through inheritance.
    I suppose a dynamic_cast will help here ? But I'm not sure.

    Would this work:

    FileAccess *FileDev = new FileTypeXDevice() ; // FileTypeXDevice inherits
    from FileAccess AND Device, DeviceA etc.

    Function(FileDev) ; // Where the function takes a Device pointer (Function
    (Device *MyDevice) // This won't work
    Function(dynamic_cast<Device*>(FileDev)) ; // this would compile but would a
    the pointer be passed as a Device pointer /

    Wow, this post has gotten way longer than I planned


    --

    Best Regards,
    Peter
     
    Peter, Nov 5, 2011
    #1
    1. Advertising

  2. Peter

    Peter Guest

    > In a bit less ideal world you would have a function IsDevice() or
    > something like that which would return true or false appropriately.


    Yes, something I have thought about as well. Implement a function:
    IsVirtual() that returns true if it is the file-access variant of the
    device.

    > Do they expect Device
    > interface?


    Yes.

    Each device (A/B) IS A device and both of them have many common
    functionality.
    Of course through virtual functions specific IO issues etc. are handled
    differently.
    But that's exactly the point, because a Read() is a Read(), let the
    device(A/B) class itself decide how to handle that Read() best.

    There is a lot of code that uses the Device pointer and that code doesn't
    need to
    know whether its device A or B to perform IO etc.
    Or a derived from A or B (e.g. access from file) device for instance

    I also need to be able to distinguish a "file"-device from a real
    device, and instead of having to do the check twice, to see if it's the file
    variant of A or the file variant of B, I would like to get a pointer that
    works for both, since the file-devices will also have special functions such
    as FileName() etc. that the base class device doesn't have and personally I
    don't think it feels right to have the base class device have a virtual
    functions that relate only really to the file-access derived classes.
     
    Peter, Nov 6, 2011
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. E11
    Replies:
    1
    Views:
    4,789
    Thomas Weidenfeller
    Oct 12, 2005
  2. Eric Lilja
    Replies:
    3
    Views:
    349
    Alf P. Steinbach
    Mar 6, 2005
  3. Replies:
    5
    Views:
    320
    John Carson
    Apr 16, 2005
  4. Wybo Dekker
    Replies:
    1
    Views:
    367
    Yukihiro Matsumoto
    Nov 15, 2005
  5. vdvorkin
    Replies:
    0
    Views:
    415
    vdvorkin
    Feb 10, 2011
Loading...

Share This Page