0

我想將類A的成員函數作爲參數傳遞給全局函數。我該做些什麼才能做到這一點?另外,這是一個好主意嗎?上下文:我想這樣做是因爲(同義詞)doSomething(...)是一個非常通用的函數,用於main()以及不同的類。因此,我可以避免在項目中有相同代碼的多個副本。什麼是替代品(如果它不是最佳的)?將類成員函數作爲參數傳遞給全局函數

#include <iostream> 
using namespace std; 

double doSomething(int i, double (*f)(double)) { return (*f)(i); } 

class A{ 
public: 
    A(double x) : number(x) {} 
    double times(double i) { return ::doSomething(i, &A::multiply);} //calles the global function and gives a member function as parameter 
    double multiply(double i) {return number*i;} 
private: 
    double number; 
}; 

int main() { 

    A obj(5.0); 
    cout << obj.times(3.5) <<endl; 

    return 0; 
} 

編譯器抱怨:

../src/test5.cpp: In member function ‘double A::times(double)’: 
../src/test5.cpp:17:63: error: cannot convert ‘double (A::*)(double)’ to ‘double (*)(double)’ for argument ‘2’ to ‘double doSomething(int, double (*)(double))’ 
    double times(double i) { return ::doSomething(i, &A::multiply);} //calles the global function and gives a parameter member function as parameter 
                  ^
../src/test5.cpp:17:65: warning: control reaches end of non-void function [-Wreturn-type] 
    double times(double i) { return ::doSomething(i, &A::multiply);} //calles the global function and gives a parameter member function as parameter 

回答

1

doSomething函數需要自由函數指針(免費功能是指非成員函數)。您嘗試將成員函數指針傳遞給它。這不起作用。爲什麼?當你有一個免費的功能,說void f(double),你可以簡單地把它叫做:

f(3.14); 

在另一方面,當你有一個成員(非靜態)函數,調用它,你需要一個對象,如:

obj.m(3.14); 

並且無法在沒有對象的情況下調用成員函數。所以成員函數不能與自由函數互換使用,因爲它們以不同的方式被調用。想想doSomething函數中的(*f)(i)調用 - multiply要調用的對象A是什麼?

您的設計需要重新思考。如果你想分享代碼,也許你需要一些類層次結構和基類中的通用代碼?

1

用C++ 11你可以這樣做:

#include <functional> 

typedef std::function<double (double)> do_something_function; 
double doSomething(double i, do_something_function f) { return f(i); } 

class A{ 
    public: 
    A(double x) : number(x) {} 
    double times(double i) { 
     do_something_function f = [this] (double i) { 
      return this->multiply(i); 
     }; 
     return ::doSomething(i, f); 
    } 
    double multiply(double i) { 
     return number * i; 
    } 

    private: 
    double number; 
}; 
0

調用通過指針類的non-static功能部件,從方法上有所不同的方式你做對獨立的功能,因爲指針實例需要

#include <iostream> 
using namespace std; 

class A; 
typedef double (A::*f)(double); 
double doSomething(double i, f p, A* ap); 

class A { 
public: 

    A(double x) : number(x) { 
    } 

    double times(double i) { 
     return ::doSomething(i, &A::multiply, this); 
    } //calles the global function and gives a member function and pointer to A 

    double multiply(double i) { 
     return number*i; 
    } 
private: 
    double number; 
}; 

double doSomething(double i, double (A::*fp)(double), A* ap) { 
    return (ap->*fp)(i); // call *fp on *ap 
} 

int main() { 

    A obj(5.0); 
    cout << obj.times(3.5) << endl; 

    return 0; 
} 

example

+0

在你的榜樣,我會仍然需要declair對象的類型'doSomething'希望。這意味着我仍然需要其他對象的相同代碼的副本。我認爲Wojtek Surowka重新考慮我的設計是正確的。謝謝您的回答。 – dani

相關問題