Home > front end >  Can a parent class which is reinterpreted as a child class use the child's functions in its fun
Can a parent class which is reinterpreted as a child class use the child's functions in its fun

Time:11-16

I want to call the child's function from parent's function in reinterpreted class, like below.

Example

#include <iostream>

class A {
public:
    void func1() {
        // some code
        func2();
        // some code
    }
protected:
    virtual void func2() {
        printf("class A\n");
    }
};

class B : public A {
protected:
    virtual void func2() {
        printf("class B\n");
    }
};

int main() {
    A* ab = new A();
    ab->func1(); // this print "class A"

    B* bab = reinterpret_cast<B*>(ab);
    bab->func1(); // this also print "class A"
    // I want to print "class B" when I use bab->func1() 
}

In this situation, Is there any way to print class B using the reinterpreted class bab without redefining func1?

CodePudding user response:

For C polymorphism to kick in, you must create an instance of the derived class somewhere, but you can store a pointer to the base class. Using the base-class pointer will dispatch to the overridden functions of the derived class. So your definition of A and B is fine, your usage in the main function is not. reinterpret_cast is not intended for this.

#include <iostream>
#include <memory>

class A {
public:
    void func1() {
        // some code
        func2();
        // some code
    }
protected:
    virtual void func2() {
        printf("class A\n");
    }
};

class B : public A {
protected:
    virtual void func2() {
        printf("class B\n");
    }
};

int main() {

    {
    // This works, but don't do this. Naked "new" is not modern C   and dangerous.
    A* ab = new B();
    ab->func1();
    delete ab; 
    }

    {
    // VARIANT 2: use smart pointers
    std::unique_ptr<A> ab = std::make_unique<B>();
    ab->func1();
    }

    {
    // VARIANT 3: A non-smart pointer is okay, as long as it 
    // 1. references an existing allocated object
    // 2. the pointer does not outlive the object it points to
    B b;
    A* ab = &b;
    ab->func1();
    }

    {
    // VARIANT 4: Like Variant 3, but with reference instead of pointer
    B b;
    A& ab = b;
    ab.func1();
    }
}

Output

class B
class B
class B
class B

https://godbolt.org/z/8e5E85nx5

EDIT: Try to avoid allocation with new. Any memory allocated in this fashion must be freed by you using delete and it is very easy to forget (I did when I first wrote this answer, kinda proving my point). Even if you do delete the memory at the end of your function, there is the possibility that your code never reaches this statement, e.g. if exceptions are thrown somewhere between new and delete.Here is some further reading:

  • Related