调用从基类派生类的功能,无需使用虚拟函数
嗨假设我有这样调用从基类派生类的功能,无需使用虚拟函数
// base class
class A {
public:
int CallMyFct(PtrToFCT what){
return what(10);
}
};
class B : public A {
int myInt;
public:
B():myInt(10){}
int myFct1(int val){
return myInt+val;
}
int myFct2(int val){
return myInt*2+val;
}
void Call(void){
int rez1=CallMyFct(&myFct1);
if (rez1!=20)
cout << "You are wrong" << endl;
int rez2=CallMyFct(&myFct2);
if (rez2!=30)
cout << "You are wrong" << endl;
}
};
代码现在我需要调用这些MyFct1,MyFct2等从基类,但我不能使用虚拟功能。所以它就像继承的倒置一样。我不知道这是否可能。你认为mem_fun或其他适配器功能可以在这里工作吗?
我实际上需要弄清楚什么是PtrToFCT,以及如何在CallMyFCT中传递myFct1。
感谢
你必须定义被称为static
的功能,并提供额外的参数传递给他们的对象实例(而不是this
,如果称为普通成员函数,他们会得到)。
感谢..我想到了这一点,而这个工程,但如果我不希望使用静态比它可能吗? –
这不是微不足道的,因为这些类是相关的。对于不相关的类(其中一个的定义不依赖于另一个的定义,你可以直接使用)。你可以做的是传递原始指针,并将它们投射到实现类A的单独文件中的B :: function指针中。这很丑陋,我不会那样做(我不会做你在做的事情所有的,它的设计不好) – littleadv
嗯..是的,你对错误的设计是正确的,实际上我只是在学习STL,当我了解mem_fun时,我认为这种事情是可能的,显然不是。 –
你可以做你喜欢什么更干净地[boost::function<>]
1,也被称为std::function
从C++ 2011 <functional>
。你不明白为什么你不能使用虚拟功能。目前尚不清楚这种方法是否比虚拟功能提高了性能,但还有其他一些不使用虚拟功能的原因。
在任何情况下,这都符合(我的解释)您从基类调用函数的要求,根据实际的派生类而行为不同,而不使用虚函数。你想要的使用例子并不完全清楚。如果这种机制不能满足您的需求,请澄清需求。
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
class A{
protected:
typedef boost::function<int (int)> CallbackFunc;
// A knows it can call *something* with a particular signature
// but what is called can be overridden by the derived class.
CallbackFunc m_callbackFunc;
public:
A()
{
m_callbackFunc = boost::bind(&A::same,this,_1);
}
int same(int val) const { return val; }
int simulateVirtual(int val) const { return m_callbackFunc(val); }
}; //end class A
class B : public A {
int m_offset;
public:
B(int offset) : m_offset(offset) {
m_callbackFunc = boost::bind(&B::offset,this,_1);
}
int offset(int val) const { return m_offset + val; }
}; // end class B
int main() {
A* pA = new A;
A* pB = new B(42);
std::cout << "simulateVirtual(10) called on a 'real' A instance="
<< pA->simulateVirtual(10) << "\n";
std::cout << "simulateVirtual(10) called via A* on a B instance="
<< pB->simulateVirtual(10) << "\n";
delete pB; // in real life I would use shared_ptr<>
delete pA;
return 0;
} // end main
[CRTP(https://secure.wikimedia.org/wikipedia/en/wiki/Curiously_recurring_template_pattern)可以帮助 – rlduffy