Thread: How would you design the relationship between these two classes?

  1. #1
    Set Apart -- jrahhali's Avatar
    Join Date
    Nov 2002
    Posts
    256

    How would you design the relationship between these two classes?

    Say you had two classes:

    Code:
    class Adult {
        public:
            void crawl() {...}
            void run() {...}
    }
    
    class Baby {
        public:
            void crawl() {...}
    }
    method crawl() uses the same implementation in both classes. How would you 'factor out' method crawl into a base class and have the relationship make sense? I can only think of the following solutions, none of which seem very good to me.

    1. I could have Adult inherit from Baby (deleting Adult's crawl() implementation), but then i would be saying that an Adult 'is-a' Baby.

    2. I could compose a Baby object in Adult so as to re-use method crawl(). But again, this would imply that an Adult is composed of a Baby, which doesn't make a whole lot of sense.

    3. I could have a Human base class with a concrete implementation of crawl() which both Adult and Baby extend from. However, Baby would be completely empty.

    4. I could have a Human base class with a concrete implementation of method crawl(), which both Adult and Baby compose. In this case, Baby would have a crawl() method that simply calls crawl() in Human.

    Is there a better way?
    Clear the mines from our Shazbot!
    Get the enemy Shazbot!

  2. #2
    Advanced Novice linucksrox's Avatar
    Join Date
    Apr 2004
    Location
    Michigan
    Posts
    198
    I think you have the right idea between 3 and 4, depending on what exactly you want the crawl() function to do. 1 and 2 don't use inheritance correctly. An example I like is the Animal class which has a makeNoise() function and then is implemented in sub-classes such as Horse which will neigh when calling makeNoise() or dog which will bark when calling makeNoise().
    "What are all you parallelograms doing here?" - Peter Griffin (to Joe and his wheelchair buddies)

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You could use 3. But make sure make a typedef for Baby as an alias to Human. Remember that this would be an implementation detail (hide it, hide it, hide it!).
    Another way might be to create a common base class with protected or private inheritance.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    Another way to go is to have both adult and baby inherit from a human baseclass where you have a member "move" (bad name i know given the std::move in c++11) which takes an enum with the mode of movement. This way you can have babys implementation of move when you send it the enum value corresponding to crawl and throw an exception for all others. Adult can have implementation for crawl, walk, run and so on.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Don't typedef Baby to Human. Make it a real class. If it's empty, so what? An empty class doesn't actually really cost you anything (maybe you have to write some forwarding constructors, but not if you have a C++11 compiler), but gains you a lot if you want to put something in there later. Typedefs are syntactically incompatible in a number of cases.

    That said, I like also like Shakti's solution.

    If it's really only about sharing the implementation of the crawl() method and you don't care about the actual relationship between the classes, consider writing a normal function that takes references to the relevant class members to work on, or a mixin/trait class.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The two concepts Adult and Baby fail the basic substitution principle. A baby is not a kind of adult, nor is an adult a kind of baby.

    It doesn't seem to make sense for either one of them to inherit from the other.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Hmm... one thing about deriving Baby and Adult from a Human abstract base class is that if "growing up" is a possible course of action, then the Baby object will have to be replaced with an Adult object with various other data (and perhaps family relationships, etc) remaining mostly the same.

    Some instance of the strategy pattern where say, a Human object has a HumanBehaviour (or something more specific) could then allow for the substitution of BabyBehaviour with AdultBehaviour when the time comes.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Array, pointer relationship.
    By Kitt3n in forum C++ Programming
    Replies: 7
    Last Post: 05-25-2010, 10:53 AM
  2. Getting the relationship between two numbers
    By Mavix in forum C# Programming
    Replies: 8
    Last Post: 01-30-2008, 01:05 PM
  3. relationship between std and iostream
    By sawer in forum C++ Programming
    Replies: 4
    Last Post: 01-24-2006, 11:23 AM
  4. What is your current relationship status?
    By Welshy in forum A Brief History of Cprogramming.com
    Replies: 27
    Last Post: 05-18-2005, 04:49 AM
  5. problem with the has-a relationship (aggregation)
    By geo in forum C++ Programming
    Replies: 1
    Last Post: 02-26-2005, 05:13 PM