Thread: Clone an object in a polymorphic class?

  1. #1
    Algorithm engineer
    Join Date
    Jun 2006
    Posts
    286

    Clone an object in a polymorphic class?

    Hi, I have a question about cloning objects in polymorphic classes:

    In a lab we are doing in school we are going to create an expression tree, looking for example like this when it's printed:

    Code:
        5
       /
      *
       \
        7
     /
    +
     \
      6
    which represents the expression 5*7+6 in tree form. Each node in the tree is of a class called node, then there's a subclass called node_operator. Each class under node is supposed to have a clone function, so that it is possible to clone a whole tree by just cloning the node at the lowest level.

    node_operator in turn, is an abstract class which have subclasses called node_plus, node_minus, node_times etc. Each object which is of a derived class from node_operator will have two and only two data members, left_node and right_node. To clone a object from any subclass of node_operator, it will be the exact same code:

    Code:
    node_x* node_x::clone() {
        return new node_x(left_child->clone(), right_child->clone());
    }
    Where x is the name operator. Since x is different for every subclass, the same function can't be used, hence we need a virtual clone function. What I would like to do is something like this (only having to write the function once instead of having to write almost the same code in every subclass):


    Code:
    virtual node_operator* clone();
    
    ...
    
    virtual node_operator* node_operator::clone(){
        return new typeof(this*) (left_child->clone(), right_child->clone());
    }
    If only typeof would have existed in C++ (as it does in C) the code would have worked, and the function I mentioned above (that one with node_x) would have successfully been copied to every subclass node_x. But now typeof doesn't exist in C++. Can I use something else instead of typeof, or do I have to write the clone function in every subclass? Having to write the same code in every subclass feels bad. Besides, the risk of creating a bug will increase. Why did they remove typeof from the beginning, when they created C++ from C?
    Come on, you can do it! b( ~_')

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    There is no typeof in standard C. Have you learned about templates yet? Maybe you could template it.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Quote Originally Posted by quzah View Post
    There is no typeof in standard C. Have you learned about templates yet? Maybe you could template it.
    Can you give a pseudo-code how he would do that?

  4. #4
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Sounds like a good use of the prototype pattern.
    Prototype Design Pattern
    There is the UML of how you could design your class structure.

    Yes each class needs to know "how" to copy itself.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Are you really supposed to print that for the expression tree? Why? The expression tree would be this:
    Code:
          +
         / \
        /   \
       *     6
      / \
     /   \
    5     7

  6. #6
    Algorithm engineer
    Join Date
    Jun 2006
    Posts
    286
    Expression trees can be displayed in many ways, it can also look like this:

    Code:
            -- 5
           |
        -- *
       |   |
       |    -- 7
       |
    -- +
       |
        -- 6
    But the form I used in the first post was the way our supervisor used as an example, because it is the easiest to program.
    Come on, you can do it! b( ~_')

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by TriKri View Post
    Expression trees can be displayed in many ways, it can also look like this:

    Code:
            -- 5
           |
        -- *
       |   |
       |    -- 7
       |
    -- +
       |
        -- 6
    But the form I used in the first post was the way our supervisor used as an example, because it is the easiest to program.
    Oh I see sideways. I was reading it downwards instead of to the right. Carry on then.

    As to that, C stole typeof from C++'s typeid, so that shouldn't really be a problem.

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    This is definitely a candidate for templatization.

    Code:
    template < typename Op >
    class BinaryNode
    {
    public:
        BinaryNode( Node *lhs, Node *rhs )
          : mLhs( lhs ),
            mRhs( rhs )
        {
        }
    
        Value Evaluate() const
        {
            return Op::Evaluate( lhs->Evaluate(), rhs->Evaluate() );
        }
    
        BinaryNode *Clone() const
        {
            return new BinaryNode( mLhs->Clone(), mRhs->Clone() );
        }
    
    private:
        Node *mLhs;
        Node *mRhs;
    };
    Now, you can define for instance:

    Code:
    class AdditionOperator
    {
    public:
        static Value Evaluate( Value lhs, Value rhs )
        {
            return lhs + rhs;
        }
    };
    And then:

    Code:
    typedef BinaryNode< AdditionOperator > AdditionNode;
    Now, you just have to implement the operators themselves, and forget about cloning.

    (My code is not exception safe. In general, none of the examples I give are exception safe unless otherwise claimed)
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  9. #9
    Algorithm engineer
    Join Date
    Jun 2006
    Posts
    286
    Thank you brewbuck, I'll remember that next time I get in the same situation!

    -Kristofer
    Come on, you can do it! b( ~_')

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Inventory tracking of dynamically allocated items
    By Mario F. in forum C++ Programming
    Replies: 11
    Last Post: 07-23-2006, 05:39 PM
  3. Mmk, I give up, lets try your way. (Resource Management)
    By Shamino in forum Game Programming
    Replies: 31
    Last Post: 01-18-2006, 09:54 AM
  4. My Window Class
    By Epo in forum Game Programming
    Replies: 2
    Last Post: 07-10-2005, 02:33 PM
  5. C++ Class Object Collection
    By Visual Develope in forum C++ Programming
    Replies: 3
    Last Post: 05-04-2002, 04:48 PM

Tags for this Thread