Why is an assignment to a base class valid, but an assignment to a derived class a compilation error?

前端 未结 6 1419
旧巷少年郎
旧巷少年郎 2021-01-31 08:27

This was an interview question. Consider the following:

struct A {}; 
struct B : A {}; 
A a; 
B b; 
a = b;
b = a; 

Why does b = a;

6条回答
  •  遇见更好的自我
    2021-01-31 09:03

    It's true that a B is an A, but an A is not a B, but this fact is only directly applicable when you're working with pointers or references to A's and B's. The problem here is your assignment operator.

    struct A {}; 
    struct B : A {};
    

    Is equivalent to

    struct A {
       A& operator=(const A&);
    }; 
    struct B : A {
       B& operator=(const B&);
    };
    

    So when you're assigning below:

    A a; 
    B b; 
    a = b;
    

    The assignment operator on a can be called with an argument of b, because a B is an A, so b can be passed to the assignment operator as an A&. Note that a's assignment operator only knows about the data that's in an A, and not the stuff in a B, so any members of B that aren't part of A get lost - this is known as 'slicing'.

    But when you're trying to assign:

    b = a; 
    

    a is of type A, which is not a B, so a can't match the B& parameter to b's assignment operator.

    You would think that b=a should just call the inherited A& A::operator=(const A&), but this is not the case. The assignment operator B& B::operator=(const B&) hides the operator that would be inherited from A. It can be restored again with a using A::operator=; declaration.

提交回复
热议问题