簡體   English   中英

成員函數指針c ++

[英]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); 不是成員函數指針,而只是普通函數指針。

如果使用了真正的成員函數指針,則該函數還必須具有您不希望使用的AB實例。

如果您無法使A1dB2d靜態,則其他選擇是使您的Optimize1dOptimize2d模板函數采用模板化函子:

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);

兩者都可以通過捕獲AB實例的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的類來定義自己的函子。 該類將必須在成員變量中存儲指向AB實例的指針或引用:

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()函數來使自己的AB類成為仿函數?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM