Search code examples
c++castingdowncast

Converting base to derived class


In the following code although the instances of subclass are getting pushed on the stack of base class but while retrieving(top operation) an element and storing it in derieved class object, the compiler is generating an error.

#include <cstdio>
#include <stack>

using namespace std;

class base{};

class sub : public base{
public:
    int a;
    sub (int A){ a=A;}
};

int main(){
    stack<base> st;

    sub A = sub(10);
    sub B = sub(20);

    st.push(A);
    st.push(B);
    printf("%d\n", (int)st.size());

    sub C = (sub)st.top();

    return 0;
}

Error:

 In function ‘int main()’:  
24:22: error: no matching function for call to ‘sub::sub(base&)’  
24:22: note: candidates are:  
11:2: note: sub::sub(int)  
11:2: note:   no known conversion for argument 1 from ‘base’ to ‘int’  
8:7: note: sub::sub(const sub&)  
8:7: note:   no known conversion for argument 1 from ‘base’ to ‘const sub&’  

Please suggest any way by which I can typecast the retrieved base class object to derieved class.


Solution

  • That's an error to expect, naturally because an object of the class base and another of the class sub are different to the compiler. When you equate an r-value, a, to another value, b, you're calling a's copy-constructor with b as an argument. By default, if you don't implement this in your class declaration, C++ will perform a per-member copy of b to your members in a. However, if a and b are of different types, what members will be copied is ambiguous to the compiler, even if one is derived from the other (as there's always chance there will be additional members in it, thus increasing the size and changing the structure of the class of the object).

    As Joachim answered in the comments, for polymorphism to work, you need to deal with pointers or references. You can't use references because you can't have containers of references.

    stack<base*> st;
    
    sub A = sub(10);
    sub B = sub(20);
    
    st.push(&A);
    st.push(&B);
    printf("%d\n", (int)st.size());
    
    sub *C = (sub*)st.top();