2012-04-15 63 views
1

在网上,我发现了一些关于函数对象(被调用者)的例子,但他们没有演示如何将它们用作回调函数(调用它们的函数)的参数,而仅仅是它使用sort或for_each时使用。因此,我做了一个自己:非STL函数对象回调用法

class CBase 
{ 
public: 
virtual int operator()(int a, int b) 
{ 
    return 10; 
} 
}; 

class CSmaller: public CBase 
{ 
public: 
int operator()(int a, int b) 
{ 
    return a < b; 
} 

int Compute(int a, int b) 
{ 
    return a < b; 
} 
}; 

class CLarger: public CBase 
{ 
public: 
int operator()(int a, int b) 
{ 
    return a > b; 
} 

int Compute(int a, int b) 
{ 
    return a > b; 
} 
}; 

int caller(CBase &f, int x0, int x1) 
{ 
return f(x0,x1); 
} 

int main() 
{ 
CLarger callee1; /*this callee is being called by caller*/ 
CSmaller callee2; /*idem*/ 
int q=caller(callee1,0,1); 
int z=caller(callee2,0,1); 
printf("%d\n",q); 
printf("%d\n",z); 
} 

以这种方式实现的(因为它常常只能由一个普通的名字/类“模板”开头)的STL函数对象(如较大者)?也就是说,它们(CLarger和CSmaller)是否有一个关系/共同协调者,并为每个类扩展一个虚拟函数,或者它们是否也可以是一些通用函数对象(只要它们使用两个参数实现()运算符)?这样的(虽然不是测试):

template<class F> 
float integrate(const F &f,float x0,float x1) 
{ 
..f(x)..; 
} 

float derive(const F &f,float x0,float x1) 
{ 
..f(x)..; 
} 

class CSquare 
{ 
public: 
float operator()(float x) 
{ 
    return x*x; 
} 
}; 

class CTwoX 
{ 
public: 
float operator()(float x) 
{ 
    return 2*x; 
} 
}; 

如果这是正确的方式,如何将这些非相关的类可以在非STL的方式来实现?我知道使用模板来保持底层机制(这样它们是相关的),但只有类型是不同的。但是这样的关系(即同一个管理者)需要吗?

在函数对象中使用overloaded()只是为了方便吗?因为我也可以使用CLarger的Compute。例如,我也可以将CCompute类中的那些分离的类(对其不同功能使用虚拟类)合并为较大和较小的成员。顺便说一句,我想我可以把派生和整合在一个类中。我的问题是否有意义,或者我的想法与STL理论相矛盾?

+0

接口相匹配的任何东西。注意:STL!=标准库。 – Griwes 2012-04-15 17:38:55

回答

1

你可以去任何一种方式:继承或模板。但是,这也不是要求。 STL函数是模板化的,这意味着只要表达式f(x)按需要工作,您就可以传递任何东西给f(例如,函数指针,函子 - 您称之为被调用者)。

注意:f(x)只是一个例子,参数的确切数量取决于所使用的特定STL函数。

继承的优点是可以将常见行为封装在基类中,并在运行时根据实际类型执行。

模板的优点是你可以使用它们的任何类型(基于模板参数) - 因此,虽然你可以在每个类中重载operator(),但创建可处理每种类型的模板类可能更容易(使用模板特若特殊处理需要某些类型)

注意,当你使用模板,它会创建一个不同类型的每一个实际的模板参数类型组合

+0

问题是,stdlib算法接受函子_by_value,所以如果试图将函数从指针/引用传递到基类,并因此虚拟函数不会以多态方式行为,则会发生对象切片。出于这个原因,模板优于继承。 – ildjarn 2012-04-15 16:46:02

0

STL算法,它接受一个函数参数(为例如,谓词)通常不会在意参数是如何创建的,只要它匹配“函数样”接口;它需要做的一切都是推断与模板参数推导类型沿

template< typename FwdIter, typename Pred > 
FwdIter find_if(FwdIter first, FwdIter last, Pred pred); 

/* .. etc ... */ 

bool is_equal_to_one(int n) { return n == 1; } 

int main() 
{ 
    std::vector<int> foo; 
    std::vector<int>::const_iterator iter; 
    iter = std::find_if(foo.begin(), foo.end(), is_equal_to_one); 
} 

行有针对Pred类型太多不同的可能的方法来实现做任何其他方式(函数,仿函数,一个std :: function ...)。 find_if函数将依赖于与bool (*FwdIt)

+0

注意:STL!=标准库。 – Griwes 2012-04-15 17:39:43

相关问题