基本上,我有一个运行某种算法的模板化类,该算法需要一个similarity(T t1, T t2)
函数,该函数返回一个double,用于定义类型T的两个对象的相似程度。该相似度函数根据T的定义而变化很大,因此该类的调用者需要定义相似度函数。我假设函数指针是有序的,但是如何将函数指针中的函数保存为算法中使用的成员函数?
也就是说,我想在类'构造函数中传递similarity(T t1, T t2)
,并且能够在整个类中将其作为成员函数调用。我怎么做?感谢
答案 0 :(得分:2)
您无法在运行时向类中添加成员函数。
您可以编写一个通过函数指针调用提供的函数的成员函数:
class MyClass {
typedef double (*similarity_fn_type)(T t1, T t2);
similarity_fn_type similarity_fn;
public:
MyClass(similarity_fn_type ptr) : similarity_fn(ptr) {}
double similarity(T t1, T t2) {
return similarity_fn(t1, t2);
}
};
或者,您可以将similarity_fn
成员公开。调用它的语法会使它看起来像一个成员函数,但你可能不认为它是一个很好的封装。
答案 1 :(得分:1)
有更清洁,面向对象的方法。其中之一是使用该函数传递一个对象,类似于Java允许重新实现与Comparator类的比较。这意味着创建一个基类(将该函数作为纯虚函数)和每个similarity()
实现的子类。
在您的情况下,您可能会发现C ++ 11用于实现比较和散列函数的解决方案更有用。它涉及创建特殊功能对象。有关示例,请参阅std::less和std::hash。
答案 2 :(得分:0)
我做了类似的事情来抽象迭代集合的过程。我使用谓词来指定实际的搜索条件:
void MyClass::Copy(Class &destination, const Class &source, const std::function<bool (const Effect&)> &predicate)
{
for (size_t i = 0; i < Effect::Max; ++i)
{
const Effect *const pEffect = source.GetEffect(i);
if (predicate(*pEffect))
{
// Do something
}
}
}
void MyClass::CopyInner(Class &destination, const Class &source)
{
this->Copy(destination, source, [](const Effect &effect)
{
return effect.IsInner();
});
}
注意:这使用了一些C ++ 11功能。
答案 3 :(得分:0)
定义适当类型的const
函数指针成员:
typedef double(*Similarity)(T, T);
const Similarity similarity;
让构造函数接受该类型的函数:
Class(Similarity f) : similarity(f) {}
然后调用该函数与调用普通成员函数具有相同的语法:
frobnicate(similarity(foo, bar));
如果该成员是public
,则无法将其更改为您,因为它是const
。