我想创建一个带有基类参数的函数指针。我希望能够创建一个指针可以指向的函数,但是它需要一个派生类的参数。然后,我希望能够使用派生类调用函数参数,并让它预先形成一个函数,就好像参数是派生类一样。我希望能够做到这样的事情:
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 ++来完成这项工作吗?
答案 0 :(得分:3)
所以,换句话说,你想拥有一个带有Base
对象参数的函数,并使用该参数,就像它实际上是一个派生对象一样。
所以基本上(psudocode):
void DoSomething (Base obj)
{
obj.DoSomethingWithDerived();
}
为了实现这一目标,您需要做两件事:
Base
多态。Base
- 而不是按值Base
。 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
中的成员函数已被覆盖},那个定义接管了。