[英]member function pointers c++
我已經查看了訪客模式和指向成員函數指針的最佳答案。 但是我仍然不知道如何設計以下(相當簡單)的方案。
在一個基本示例中,我想要一個優化器類。 給定另一個類的成員函數,它將找到一些最佳值。 像這樣:
class Optimizer{
public:
typedef double (*Func1d)(double);
typedef double (*Func2d)(double,double);
void Optimize1d(Func1d* f1Ptr, double& x);
void Optimize2d(Func2d* f2Ptr, double& x, double& y);
};
和兩個示例類:
class A {
double A1d(double x){return x;}
};
class B{
double B2d(double x, double y){return x+y;}
};
和主要功能,我希望可以使用以下功能:
void main()
{
Optimizer opt;
double xA_opt, xB_opt, yB_opt;
opt.Optimize1d(&A::A1d,xA_opt);
opt.Optimize2d(&B::B2d, xB_opt, yB_opt);
}
但是,我仍然無法正常工作。 我不希望優化器直接保存指向A和B類型對象的指針; 因為那樣他就需要熟悉這些對象。
我希望這個問題有意義。 謝謝!
上面的代碼中的問題在於,在C ++中,指向成員的函數是一種獨特的類型,與“常規”函數指針不兼容。
這個typedef
typedef double (*Func1d)(double);
在C和C ++代碼中都是合法的,並且您可以在此類型中使用C樣式的“免費”函數。
但是在您的主要功能的這一行:
opt.Optimize1d(&A::A1d,xA_opt);
您試圖將一個指針作為Func1d
傳遞給成員函數, Func1d
無法完成。 一方面,您也不能在沒有該類型對象的指針的情況下調用成員函數的指針,並且還必須傳遞該指針。
最簡單的事情是包括頭文件<functional>
並為此使用std::function<double(double)>
。 (假設您擁有C ++ 11,否則可以使用boost::function
。)
您還可以做其他事情,例如使用注釋中建議的虛擬成員分派。 (IMO不太優雅。)
您也可以使optimize
函數成為模板函數,並接受模板化類型的對象等。但是真正的std::function
是到達此處的方法,它將為您處理所有這些細節。
問題是typedef double (*Func1d)(double);
不是成員函數指針,而只是普通函數指針。
如果使用了真正的成員函數指針,則該函數還必須具有您不希望使用的A
或B
實例。
如果您無法使A1d
和B2d
靜態,則其他選擇是使您的Optimize1d
和Optimize2d
模板函數采用模板化函子:
template<typename F>
void Optimize1d(F f1, double& x);
template<typename F>
void Optimize2d(F f2, double& x, double& y);
或std::function
:
void Optimize1d(std::function<double(double)> f1, double& x);
void Optimize2d(std::function<double(double, double)> f2, double& x, double& y);
兩者都可以通過捕獲A
或B
實例的lambda來調用:
A a;
B b;
opt.Optimize1d([&a](double x){return a.A1d(x); }, xA_opt);
opt.Optimize2d([&b](double x, double y){return b.B2d(x, y); }, xB_opt, yB_opt);
編輯:如果您沒有C ++ 11,則可以使用定義了operator()
而不是lambda的類來定義自己的函子。 該類將必須在成員變量中存儲指向A
或B
實例的指針或引用:
struct A1d {
A* a;
A1d(A& a) : a(&a) {}
double operator()(double x) { return a->A1d(x); }
};
然后,您可以構造此類的實例,並將其傳遞給模板化的優化函數:
A1d a1d(a);
opt.Optimize1d(a1d,xA_opt);
也許您甚至可以通過向它們添加一個operator()
函數來使自己的A
或B
類成為仿函數?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.