Too many datamembers

Discussion in 'C++' started by sreeni, Nov 12, 2008.

  1. sreeni

    sreeni Guest

    I have a ordinary C++ class with lot of datamembers used internally
    between methods of the same class.

    Is there any other elegant way to maintain the private datamembers.

    Please give your suggestions.
    sreeni, Nov 12, 2008
    1. Advertisements

  2. sreeni

    red floyd Guest

    Not knowing your requirements or your design, we can only guess.

    My suggestion? Refactor.
    red floyd, Nov 12, 2008
    1. Advertisements

  3. The most elegant way is to hide the implementation details of your
    class. All non-public members are an implementation detail. You hide
    these by providing an abstract class / interface and a factory
    function that creates an instance of that interface.
    Maxim Yegorushkin, Nov 12, 2008
  4. sreeni

    James Kanze Guest

    That's one way. The more idiomatic way in C++ is the
    compilation firewall idiom. Both work, but neither is totally
    without drawbacks. The abstract class/factory function, for
    example, doesn't work if users have to be able to derive from
    the interface.
    James Kanze, Nov 12, 2008
  5. How do you tell which one is more idiomatic?
    Hm... It works for me - the venerable decorator design pattern:

    #include <memory>

    struct Interface
    virtual ~Interface() = 0;
    // idiomatic functions ;)))
    virtual void foo() = 0;
    virtual void bar() = 0;
    std::auto_ptr<Interface> createInterfaceImplementation();

    class DeriveFromInterface : public Interface
    std::auto_ptr<Interface> base_implementation_;

    // disable these for simplicity
    DeriveFromInterface(DeriveFromInterface const&);
    DeriveFromInterface& operator=(DeriveFromInterface const&);

    void foo() { base_implementation_->foo(); }
    void bar() { base_implementation_->bar(); }

    : base_implementation_(createInterfaceImplementation())
    Maxim Yegorushkin, Nov 12, 2008
  6. Maxim Yegorushkin a écrit :
    The factory system requires that everything be put on the heap and use
    mechanisms to dispose of it and ensure exception safety; whereas the
    firewall idiom let you instantiate the class as any other and dynamic
    allocation is handled internally/locally.

    In this regard, the firewall idiom is a far better tradeoff for the
    intended usage here.
    Michael DOUBEZ, Nov 13, 2008
  7. True. In this case you just modify the class, but not users.
    Maxim Yegorushkin, Nov 13, 2008
  8. sreeni

    Puppet_Sock Guest

    The bulging forehead types around here have given you
    the answers. But unless you already knew them, you may
    not understand what they are talking about.

    Internal data members are not necessarily a problem,
    even if there are lots of them. What you want to try
    to do is manage the complexity. Complexity is when
    it starts to be a problem keeping track of what goes
    where, what belongs to what code, and so on.

    The drive is always to have manageable chunks of data
    to think about at one time. If you can hold an entire
    chunk of the program (code and data) in your head at
    the same time, then that's probably a good sign that
    you have got about the right size objects.

    When you design a class, you need to have an idea of
    what that class will do for you. Think of a class as
    an exporter of some task. Usually, if the task is "hold
    on to a bunch of data and offer it up when asked" or
    something like that, then your task is pretty weak.
    This is sometimes called a "thin abstraction." This is
    one way that complexity gets away from control. If you
    treat a class as just a big bag that you shovel in a
    bunch of related stuff, then you can easily lose control
    and get a large bag of hard to manage complexity.

    If your abstraction is something like "model the
    behaviour of a car" then you start to see the
    power of a class. You want your abstraction to give
    you clues as to how to design the interface.
    And how to design the internal relationships.

    So, to manage the complexity of modelling a car
    in C++, you might have a car class. Then the car
    class would have internal data members that were
    themselves instances of classes. An engine class,
    a transmission class, a driver interface class, etc.

    Just as the larger class hides details from its
    clients, so too the internal classes hide details
    from eachother. So, the engine does not need to be
    able to see the details of the internal workings
    of the transmission. The driver only needs to see
    the controls, not the details of how the inside of
    the radio works, or where the wires go from the
    turn signals, and so on.

    So, you want to examine your abstraction and see if
    you have things aligned with the problem you are
    trying to solve with your program. Is it in fact
    the case that the thing you are modelling has this
    big set of data items that need to be visible to
    eachother? If not, can you reasonably divide this
    thing into smaller, more manageable, classes?

    So, you could design a car class as one big bag.
    Everything to do with the internal guts of a car
    could be visible once you were inside the car class.
    But that would get unworkable fast. When you wanted
    to call the routine to inventory the glove
    compartment, you'd have to sort through the data
    members that told you about all the other stuff, the
    throttle position, the trunk contents, the radio
    station currently playing, the gear the car was in,
    and so on.

    But if you design the car class to contain instances
    of other classes, you can hide those details in the
    other classes. The car has a glove compartment. The
    glove compartment details hide behind a class interface.
    The car has an engine, those details hide behind a
    class interface for the engine. And maybe the engine
    has enough details that it would work to have *it*
    divide its contents up into other classes.

    So, not only do you hide details from clients of a car
    class, you hide details of one part of the car from
    the other parts of the car. That way, when the auto-
    matic transmission decides to change gears, you don't
    accidentally wind up changing the radio station also.

    In addition to helping manage complexity, there are
    gains in terms of testing, documentation, etc. If you
    have a radio class for the car, then you can take
    that radio class and test it by itself. You can
    document that code by itself. And, in principle, you
    can reuse that code in another project, because you
    have built it with a clean, easy to use interface.

    There are lots of good books on this subject. A good
    place to start (just don't let it be your last book
    on the subject) is _Code Complete (2nd edition)_
    by Steve McConnel.
    Puppet_Sock, Nov 14, 2008
    1. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.