Take the 2-minute tour ×

I have a question about C++, how to assign a Base object to a Derived object? or how to assign a pointer to a Base object to a pointer to a Derived object?

In the code below, the two lines are wrong. How to correct that?

#include <iostream>
using namespace std;
class A{
   int a;

class B:public A{
   int b;

int main(){
    A a;
    B b;
    b = a; //what happend?
    cout << b.b << endl;   

    B* b2;
    b2 = &a;        // what happened?
    cout << b->b << endl;
share|improve this question

5 Answers 5

up vote 2 down vote accepted

When an object is on the stack, you can only really assign objects of the same type to one another. They can be converted through overloaded cast operators or overloaded assignment operators, but you're specifying a conversion at that point. The compiler can't do such conversions itself.

A a;
B b;
b = a;

In this case, you're trying to assigning an A to a B, but A isn't a B, so it doesn't work.

A a;
B b;
a = b;

This does work, after a fashion, but it probably won't be what you expect. You just sliced your B. B is an A, so the assignment can take place, but because it's on the stack, it's just going to assign the parts of b which are part of A to a. So, what you get is an A. It's not a B in spite of the fact that you assigned from a B.

If you really want to be assigning objects of one type to another, they need to be pointers.

A* pa = NULL;
B* pb = new B;
pa = pb;

This works. pa now points to pb, so it's still a B. If you have virtual functions on A and B overrides them, then when you call them on pa, they'll call the B version (non-virtual ones will still call the A version).

A* pa = new A;
B* pb = pa;

This doesn't work. pa doesn't point B, so you can't assign it to pb which must point to a B. Just because a B is an A doesn't mean than an A is a B.

A a;
B* pb = &a;

This doesn't work for the same reason as the previous one. It just so happens that the A is on the stack this time instead of the heap.

A* pa;
B b;
pa = &b;

This does work. b is a B which is an A, so A can point to it. Virtual functions will call the B versions and non-virtual ones will call the A versions.

So, basically, A* can point to B's because B is an A. B* can't point to A because it isn't a B.

share|improve this answer

It makes no sense to assign a base object to a derived (or a base pointer to a derived pointer), so C++ will do its best to stop you doing it. The exception is when the base pointer really points at a derived, in which case you can use dynamic cast:

base * p = new derived;
derived * d = dynamic_cast <derived *>( p );

In this case, if p actually pointed at a base, the pointer d would contain NULL.

share|improve this answer
However, dynamic_cast does not seem to be allowed if the class doesn't contain any virtual functions. You could use a static_cast, but this means you take full responsibility. –  UncleBens Jan 30 '10 at 0:41
@UncleBens If the base class doesn't contain any virtual functions, I have to ask why you are deriving from it - it should contain at last a virtual destructor if you intend to use it for derivation. –  anon Jan 30 '10 at 9:46
Indeed, inheritance for inheriting data only is suspicious. In this case I'd actually suggest not inheriting, giving B an A member, and providing a constructor that takes A. Then you can "cast" using the constructor. –  UncleBens Jan 30 '10 at 10:42

The compiler won't allow that kind of thing. And even if you manage to do it through some casting hack, doing so makes no sense. Assigning a derived object to a pointer of a base makes sense because everything that base can do, derived can do. However, if the opposite case was allowed, what if you try to access a member defined in derived on a base object? You would be trying to access an area of memory filled with garbage or irrelevant data.

share|improve this answer
b = a; //what happend?

This is plain illegal - A is not B, so you can't do it.

b2 = &a;        // what happened?

Same here.

In neither case, the compiler wouldn't know what to assign to int b, hence he prevents you from doing that. The other way around (assigning Derived to Base) works, because Base is a subset of Derived.

Now if you would tell us, what exactly you want to achieve, we might help you.

If it's a case of assigning an A that is known to be a Derived type, you can do a cast:

A* a = new B();
B* b = dynamic_cast<B>(a);

Just remember that if a is not a B then dynamic_cast will return NULL. Note that this method works only on pointers for a reason.

share|improve this answer
Also works on references, throwing an exception in case of failure. However, dynamic_cast seems to require virtual methods (e.g add a virtual destructor to A) –  UncleBens Jan 30 '10 at 0:44

Derived object is a kind of Base object, not the other way around.

share|improve this answer

Your Answer


