tags:

views:

238

answers:

5

Hi,

I have something like that:

Class Foo : Base {.."my stuph" ..};

int main() {
   Base *b = new Base;
   Foo  f (b);   <== **error** "invalid conversion from Base to Foo."
  ..
}

How can I clone b to f?
In "my stuph" I have functions which make workout between Foo and Base.
I can't change Base to much while it's written by others.

Thanks

+4  A: 

Define a constructor that takes an argument of type Base:

Foo(const Base & b)
: Base(b) // construct the base class, using its copy constructor
{
    // plus, initialize Foo-specific member data here
}

BTW: Are you sure you want Base to be a private base class?

Tadeusz Kopec
Well, if you're going to pick nits, "are you sure the `class` keyword is capitalised?". "Are you sure you want b to be heap-allocated?". "Are you sure you can assign the result of `new B` to a variable of type `B`?". I reckon the answer to all these things is "no" ;-)
Steve Jessop
Well, I missed that class keyword is capitalized. Anyway, the compiler would complain about it so I am sure it was a typo. But having base class private by omitting access specifier is completely legal but really confusing if not intended, so I wanted to point it.
Tadeusz Kopec
Good point.
Steve Jessop
@tkopec: The problem with the question is that the code contains more typos than anything else. While your advice is good, I somewhat doubt that it is what Mariusz wants. It's no cloning operation after all. But then - he seems to be vague on the concept of cloning anyway.
sbi
+1  A: 

Provide a constructor that takes a base class or a reference to it.

MadH
+1  A: 

Give Foo a constructor which takes a Base parameter:

class Foo : public Base {
public:
    explicit Foo(const Base &b) {
        // do work to initialise Foo. You might want to include
        Base::operator=(b);
        // or you might not. Depends how Foo works, and what Base's
        // constructors do.
    }
};

Whenever you write a single-argument constructor, you should consider whether or not you want to specify "explicit".

"explicit" is there to say that the constructor should only be used where you've explicitly written a constructor call or a cast. If it's not there, then the compiler will also "implicitly" convert Base objects to Foo, for example in the following situation:

int doSomething(const Foo &f) {
    return 23;
}

Base b;
doSomething(b); // doesn't compile
doSomething(static_cast<Foo>(b)); // does compile

If you removed the "explicit", then doSomething(b) would compile, and do the same as the second line - construct a temporary Foo object from b, and pass that to doSomething.

Steve Jessop
+5  A: 

You can't automatically make a derived class out of base one. You can do vice versa and create a base class out of the derived, however, and this might confuse you.

To do what you want, you should add proper constructor to Foo and think how you will actually create information missing in a Base instance to constitute a fully-functional Foo instance.

The constructor may look like this:

Foo(Base const& b) : Base(b)
{ /* construct info specific to Foo (absent in Bar) */ }
Pavel Shved
Thanks, it's really clear explanation.
name
+1  A: 

A clone operation is one that provides an exact copy of an object. Converting Base to Foo will is not a clone operation.

In your question, class is spelled with a capital 'C', Foo derives privately from Base, it's members (important for this question) aren't shown, Base b = new Base wouldn't compile, and I have no idea what "workout between Foo and Base" is supposed to mean. Please take the time to create a correct example that shows (only) the problem you have and provide exact descriptions of what you see and what you expect. With the question as it is, I'm not sure where to start telling you what you did wrong. I suggest you change your question to show some code that compiles (except for the problem you have).

Then I might be able to edit this answer so that it explains what's happening.

sbi