用基类作为参数制作函数指针并发送派生类

时间:2014-01-08 20:37:08

标签: c++ inheritance

我想创建一个带有基类参数的函数指针。我希望能够创建一个指针可以指向的函数,但是它需要一个派生类的参数。然后,我希望能够使用派生类调用函数参数,并让它预先形成一个函数,就好像参数是派生类一样。我希望能够做到这样的事情:

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;
}

我有什么办法可以用c ++来完成这项工作吗?

2 个答案:

答案 0 :(得分:3)

所以,换句话说,你想拥有一个带有Base对象参数的函数,并使用该参数,就像它实际上是一个派生对象一样。

所以基本上(psudocode):

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

为了实现这一目标,您需要做两件事:

  1. 使Base多态。
  2. 让您的函数将引用指针带到Base - 而不是按值Base
  3. 制作基础多态。

    C ++中的多态类是任何具有至少1 virtual方法的类。几乎在所有情况下,你都应该有一个virtual析构函数(由于不同的原因),所以你要做的就是:

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

    参考或指针参数

    如果构造一个采用Base by-value的函数:

    void DoSomething (Base obj)
    

    ...然后用派生对象调用它:

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

    最终发生的事情是der副本将在DoSomething的调用中生成,但副本将不是完整副本 - 它将会只是Base副本。所有特定于Derived的内容都是sliced away

    因此,您不必使用Base按值,而是通过引用或按指针取Base,以便不进行复制:

    void DoSomething (Base& obj);
    

答案 1 :(得分:1)

让我们看看此示例代码是否具有启发性。

#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;
}

在doSomething中,bob被视为Base对象(因此process中必须有Base个函数),但因为Derived中的成员函数已被覆盖},那个定义接管了。