BlueSpud
BlueSpud

Reputation: 1623

Making a Function Pointer With A Base Class as a Parameter and Sending a Derrived Class

I want to make a function pointer that takes a parameter of the base class. I want to be able to create a function that pointer can point to but have it take a parameter of the derived class. I then want to be able to call the function parameter with the derived class and have it preform a function as if the parameter was the derived class. I want to be able to do something like this:

void(*pointer)(Base);
class Base
{};

class Something : public Base
{
public:
    float f;
    int i;
};

void doSomething(Something s)
{
    //do something
}


int main()
{
    Something s;
    pointer = doSomething;
    pointer(s);

    return 0;
}

Is there anything I can do to make this work in c++?

Upvotes: 0

Views: 325

Answers (2)

tabstop
tabstop

Reputation: 1761

Let's see if this sample code enlightens.

#include <iostream>

class Base {
    public:
        int x;
        virtual void process() {std::cout << "Base: " << x << std::endl;}
};

class Derived : public Base {
    public:
        int y, z;
        virtual void process() {std::cout << "Base: " << x << " Derived: ";
            std::cout << y << " " << z << std::endl;
        }
};

void doSomething(Base& bob) {
    bob.process();
}

int main() {
    Derived foo;
    foo.x = 2;
    foo.y = 4;
    foo.z = 6;
    doSomething(foo);
    return 0;
}

In doSomething, bob is treated as a Base object (so there must be a process function in Base), but because the member function had been overridden in Derived, that definition takes over.

Upvotes: 1

John Dibling
John Dibling

Reputation: 101456

So, to paraphrase, you want to have a function that takes a Base object parameter, and uses that parameter as if it were actually a derived object.

So basically (psudocode):

void DoSomething (Base obj)
{
  obj.DoSomethingWithDerived();
}

In order to accomplish this, you need to do two things:

  1. Make Base polymorphic.
  2. Have your function take either a reference or a pointer to a Base -- not a Base by value.

Making Base Polymorphic.

A polymorphic class in C++ is any class that has at least 1 virtual method. In almost every case, you should have a virtual destructor anyway (for somewhat different reasons), so all you have to do here is:

class Base
{
public:
  virtual ~Base() {};
};

Reference or Pointer Parameter

If you construct a function that takes a Base by-value:

void DoSomething (Base obj)

...and then call it with a derived object:

int main()
{
  Derived der;
  DoSomething (der);
}

what ends up happening is a copy of der will be made in the call to DoSomething, but the copy won't be a complete copy -- it will only be a Base copy. All of the stuff that's specific to Derived will be sliced away.

So instead of taking a Base by-value, you have to take a Base either by-reference or by-pointer so that no copy is made:

void DoSomething (Base& obj);

Upvotes: 3

Related Questions