Home > OS >  function pointer to Child vs Parent
function pointer to Child vs Parent

Time:06-13

im learning cpp and found a weird compilation error i couldnt understand why i keep getting. I simplified my code to the following as an example:

#include <iostream>

class A {
public:
    static A foo()
    {
        A a;
        return a;
    }
};

class B : A
{
public:
    static B boo()
    {
        B b;
        return b;
    }
};

typedef A (*function)(void);

int main() {
    function f1 = A::foo;
    function f2 = B::boo; //error
    return 0;
}

I get the following error: "Cannot initialize a variable of type 'function' (aka 'A (*)()') with an lvalue of type 'B ()': different return type ('A' vs 'B')"

Would anyone be able to explain why it doesn't work? Since B is a child of A, B is A, so i don't understand why a function pointer from void to B isn't like a function pointer from void to A?

Any help will be appreciated, thanks!

CodePudding user response:

It is true that C allows a pointer to a child class to get converted to a pointer to the parent class (subject to certain conditions).

It is also true that C allows a reference to a child class to get converted to a reference to the parent class (also subject to certain conditions).

However, that does not mean that C allows a pointer to a function that returns a parent class to be converted to a pointer to a function that returns the child class. This is what the shown code is trying to do, and that is not allowed.

That answer your question of "why": because this is not allowed in C . As far as why, the "why"; that's mostly due to some practical considerations, but that's immaterial, that's just not allowed by the rules of C .

CodePudding user response:

Your function claims that it should return an A but boo returns a B, so:

typedef A (*A_function)();
typedef B (*B_function)();

int main() {
    A_function f1 = A::foo;
    B_function f2 = B::boo;
}

You could possibly solve it by returning a base class pointer from both functions:

class A {
public:
    virtual ~A() = default;      // for destruction via a base class pointer

    static A* foo() { return new A; }
};

class B : A { // you should probably use public inheritance
public:
    static A* boo() { return new B; } // creates a B but returns an A*
};

typedef A* (*function)();

int main() {
    function f1 = A::foo;
    function f2 = B::boo;
}

Or better, using smart pointers to not have to delete instances manually:

#include <memory>

class A {
public:
    virtual ~A() = default;

    static std::unique_ptr<A> foo() { return std::make_unique<A>(); }
};

class B : public A {
public:
    static std::unique_ptr<A> boo() { return std::make_unique<B>(); }
};

using function = std::unique_ptr<A>(*)();

int main() {
    function f1 = A::foo;
    function f2 = B::boo;
}
  • Related