[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Inheriting cloning

Posted on 2004-10-27
13
Medium Priority
?
262 Views
Last Modified: 2010-04-15
I'm a little looped on decongestiants at the moment, so I hope this is coherent. :-)

My problem is I have a set of classes which I need to be able to make deep copies of.  Normally this is done with the ICloneable interface and the Clone function, so I tried to do this.  The problem is the relationships between the classes.

public class A : B
{
    public A() { m_list = null };

    internal SortedArray m_list;

    public object Clone()
    {
        A a;

        // ????

        a.m_list = m_list.Clone();
    }
}

public class B : ICloneable
{
    public B() { Next = null; }

    internal B Next;

    public object Clone()
    {
      B b = new B();
      b.Next = Next.Clone;
    }
}

The problem is twofold.  The first obvious one is that I get a compiler error "The keyword new is required on 'A.Clone()' because it hides inherited member 'B.Clone()'."  I seem to be missing something since it seems that either there should be no error, or the error should be that I'm attempting to override non-virtual function.

The other problem is that I need A to clone the members of B, and still provide an object of type A at the line marked "//???".  How in the heck do I create the object to do that?  Sorry if this sounds rather lame, but I'm just not seeing it.
0
Comment
Question by:KurtVon
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 6
13 Comments
 
LVL 8

Expert Comment

by:Razzie_
ID: 12424026
For your first problem, yes, you need to use the 'new' keyword if you are inheriting the base method and overriding it.

Seconds, I'm not sure if I understand what you mean, but have you tried calling base.Clone(); in your clone method. This will call class B's clone method.

HTH,

Razzie
0
 
LVL 11

Author Comment

by:KurtVon
ID: 12424470
Wouldn't that cause a runtime error?  After all, teh B.Clone returns a new B, not a new A.  So if the A.Clone function looked like

new public object Clone()
{
    A a = (A)base.Clone();
    a.m_list = m_list.Clone();
}

The base.Clone returned an object of new B, and would therefore throw an exception.

From what I can see, what I need to do is somehow create an new object of class A, and then call the base Clone function into it.  Or maybe you just can't inherit cloning, so every cloned object must clone all base members too?

0
 
LVL 8

Expert Comment

by:Razzie_
ID: 12424790
Yeah that doesn't work but I didn't mean that. I just wonder why you need to call b.Clone(). What purpose does that have? If you need to get a new clone of B as well, can't you have a property b in your A class and in the clone() method use

public new object Clone()
{
   A a = new A();
   a.b = base.Clone();
   return a;
}

Is that what you mean?

   
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 11

Author Comment

by:KurtVon
ID: 12424934
How would I make such a property?  B is a base class, not a member of A, so the problem is the assignment.  Also, by overriding standard inheritance with a new, what happens when something calls the A.Clone function while thinking it is pointing to a class of type B?

cloner()
{
  B b = new A();
  B otherb = b.Clone();  // Will this call B.Clone or A.Clone?
}

It just seems odd to me that the Clone function wouldn't be virtual.
0
 
LVL 8

Expert Comment

by:Razzie_
ID: 12425084
You could make that property by using:

private B _b = null;

public B b
{
   get{ return this._b; }
   set{ this._b = value; }
}

when you'd use:

public new object Clone()
{
   A a = new A();
   a.b = base.Clone();
   return a;
}

the _b isntance would be set to the cloned object.
About your question:

B b = new A();
B otherb = b.Clone();  // Will this call B.Clone or A.Clone?

That would call B.Clone();
0
 
LVL 11

Author Comment

by:KurtVon
ID: 12425288
Okay, so clone is a dead end after all.

How do I do a deep copy of virtual objects, then?  Is there a standard interface?  It seems odd that the Clone function would be designed to kill further descending from an object.

Unfortunately I can't modify the library so much as to change inheritance into membership, there is just too much polymorphism in use throughout it.
0
 
LVL 8

Expert Comment

by:Razzie_
ID: 12425520
From what I know Clone() returns a shallow copy by default. If you need a deep copy, you'd need to Clone() every object that is a member of the object you want to clone as well, and add the cloned members. Like:

A a = new A();
a.m_list = this.m_list.Clone();
a.someOtherObject = this.someOtherObject.Clone();
return a;
0
 
LVL 11

Author Comment

by:KurtVon
ID: 12425801
From what I read, I was under the impression Copy made a shallow copy and Clone made a deep copy.  At least, that is how it appears to work with the members of Collections.

But if Clone won't work, then I need to find a method that does.  I tried just creating my own version of the Clone function as a virtual, but it doesn't seem to work

public class A : B
{
  virtual public object myClone(ref object obj)
  {
    A a;
    if (obj == null)
        a = new A();
    else
        a = (A)obj;
    base.myClone(ref a);
    a.m_list = m_list.Clone();
    return a;
  }
}

public class B : object
{
    virtual public object myClone(ref object obj)
    {
        B b;
        if (obj == null)
            b = new B();
        else
            b = (B)obj;
        b.Next = Next.myClone(null);
        return b;
    }
}

But I keep getting a compiler error that the call to the base.myClone has some invalid arguments.

By the way, I wasn't joking about being looped on decongestiants.  I'm probably not in any condition to program right now, but the deadline is looming and I have to get this project done.  Sorry if I'm coming across a bit thick at the moment.
0
 
LVL 8

Expert Comment

by:Razzie_
ID: 12428225
Hmm you can't pass a reference of class A to the base.myClone method when it takes an object as a reference. So you'd have to change it to myClone(ref B b2) or something.

also I can tell you now that b.Next = Next.myClone(null) won't work either. I doubt it will be necessary to pass them as ref parameters anyway.

Oh well it's almost 1 am here, no condition to program for me too, still I hope it helped you some :)
0
 
LVL 11

Author Comment

by:KurtVon
ID: 12473287
Sorry for the long delay.  The conjestion turned out to be pneumonia.

The parameter for myClone must be an object, since if I type it for the class it won't be overridden by the child class, which is necesary for polymorphism.  I think Im going to have to do this the ugly way, and just stream out the object to a memory stream, then read it back in.

I'm just surprised there is no proper facility for a polymorphic deep-copy function.
0
 
LVL 8

Accepted Solution

by:
Razzie_ earned 2000 total points
ID: 12474496
I concur. If you decide on doing it the ugly way, take a look at http://www.codeguru.com/forum/showthread.php?t=242411 since it might give you some ideas.
0
 
LVL 11

Author Comment

by:KurtVon
ID: 12698868
Sorry for the delay in answering.  I had hoped that somehow there would be a better way, but after implementing the ugly solution I have grown to actually appreciate it (plus it resulted in catching a bug in my code).
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Najam
Having new technologies does not mean they will completely replace old components.  Recently I had to create WCF that will be called by VB6 component.  Here I will describe what steps one should follow while doing so, please feel free to post any qu…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question