簡體   English   中英

c ++指向非靜態成員函數的指針

[英]c++ pointer to non-static member functions

我已經閱讀了許多關於非靜態成員函數指針的帖子和答案,但似乎沒有一個能夠解決我的問題。
所以我創建了一個簡短的例子來在這里復制我的問題:即使這個例子可以用不同的方式“解決”,對於最終的軟件,保持例子中的結構很重要,謝謝。

這是“Funcs.h”類的標題:

class Funcs
{
private:
  double a = 1, b = 2;

public:
  Funcs();
  ~Funcs();
  double Fun1(double X);
  double solver(double X0);
  double aaa(double(*fun)(double), double x0);
};

這是“Funcs.cpp”類的cpp:

#include "Funcs.h"

using namespace std;

Funcs::Funcs()
{
}

Funcs::~Funcs()
{
}

double Funcs::Fun1(double X) {
  double f1 = a*X;

  return f1;
}

double Funcs::solver(double X0)
{
  double result;

  result = aaa(Fun1, X0);
  return result;
}

double Funcs::aaa(double(*fun)(double), double x0)
{
  return fun(x0);
}

最后這是主要的“main.cpp”:

#include <iostream>
#include "Funcs.h"

using namespace std;

int main() {
  double x0=1;
  double result;
  Funcs funcs;

  result = funcs.solver(x0);
  cout << result << endl;

  return 0;
}

當我調用“result = aaa(Fun1, X0);”時,錯誤出現在方法 Funcs::solver 中因為我不能使用指向 Fun1 的指針,因為它是一個非靜態成員。 同時我不能讓它靜態,否則在靜態方法中看不到變量“a”。

預先感謝您的幫助。

問題是您試圖傳遞一個指向成員函數的指針,而期望傳遞一個指向非成員函數或靜態成員函數的指針。 這些是不同的類型。

這里的“fun”是一個指向函數的指針: double(*fun)(double)

這里是一個指向 Funcs 類成員函數的指針: double(Funcs::*fun)(double)

因此,您可以通過以下方式修改代碼以使其正常工作。

class Funcs
{
  // all the rest is the same
  double aaa(double(Funcs::*fun)(double), double x0);
};

double Funcs::solver(double X0)
{
  // ...
  result = aaa(&Funcs::Fun1, X0);
  // ...
}

double Funcs::aaa(double(Funcs::*fun)(double), double x0)
{
  return (this->*fun)(x0);
}

請參閱Coliru 的現場示例。

如果您想故意限制您的方法aaa以僅接受Funcs成員函數作為fun這可能是一個很好的方法。 如果您還想將非成員函數或例如 lambdas 傳遞給aaa ,請考慮改用std::function

您的問題是指向函數的指針與指向成員函數的指針不同。 閱讀獲取更多信息和清潔的方式來寫指針到成員函數。 如果您需要保留此結構,請將 aaa 設為靜態或非成員函數,將其需要的所有內容作為參數,或者將 aaa 的第一個參數更改為采用double(Funcs::*)(double)而不是double(*fun)(double) 您甚至可以重載 aaa 以支持這兩種用途。

實際上Funcs::Fun1不是double(*)(double)

任何非靜態方法都有這個簽名: return_type(*)(class_type* this, arguments...)

讓我們看看確切的類型:

//first argument of `aaa` has type double(*)(double)
double aaa(double(*fun)(double), double x0);

double Funcs::Fun1(double X) {
  double f1 = a*X;

  return f1;
}

// Fun1 has type double(Funs::*)(double)
// i.e it's a method of Funs and it takes (implicitly) first argument
// which is `this` pointer

// so that how `aaa` must  look like
double aaa(double(Funs::*fun)(double), double x0)
{
    // special sytax
    *this.*fun(x0);
}

// and that how `solver` looks like
double Funcs::solver(double X0)
{
  double result;

  // get pointer to method
  result = aaa(&Funs::Fun1, X0);
  return result;
}

如果您不熟悉指向方法的指針 - 檢查這個

我仍然是 C++ 的新手,但我知道的解決方案是讓靜態函數充當委托。 https://docs.microsoft.com/ru-ru/windows/win32/learnwin32/managing-application-state-

///按照完整代碼的鏈接了解我在說什么:)

看一下 win32 API 如何提供充當委托的靜態回調函數。 簡而言之,函數接受多個輸入,最后一個參數是調用者作為空指針傳遞的類。

static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        DERIVED_TYPE *pThis = NULL;

        if (uMsg == WM_NCCREATE)
        {
            // routine to recast back pointer to your class type so you have access to your local members with "This"
            CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;  
            pThis = (DERIVED_TYPE*)pCreate->lpCreateParams;
            SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);

            pThis->m_hwnd = hwnd;
        }

看看 lParam 是如何被轉換回 DERIVED_TYPE 的,它是你的類的一種類型,而 pThis 就像正常的 this 一樣,讓你可以訪問類成員。

暫無
暫無

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

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