ไม่มีอะไรผิดปกติกับการใช้ตัวชี้ฟังก์ชัน อย่างไรก็ตามพอยน์เตอร์ไปยังฟังก์ชันสมาชิกที่ไม่คงที่ไม่เหมือนกับฟังก์ชันพอยน์เตอร์ปกติ: ฟังก์ชันสมาชิกจะต้องถูกเรียกใช้บนอ็อบเจ็กต์ซึ่งส่งผ่านเป็นอาร์กิวเมนต์โดยนัยไปยังฟังก์ชัน ลายเซ็นของฟังก์ชันสมาชิกของคุณข้างต้นจึงเป็นเช่นนั้น
void (aClass::*)(int, int)
มากกว่าประเภทที่คุณพยายามใช้
void (*)(int, int)
แนวทางหนึ่งอาจประกอบไปด้วยการสร้างฟังก์ชันสมาชิกstatic
ซึ่งในกรณีนี้ไม่จำเป็นต้องเรียกใช้อ็อบเจ็กต์ใด ๆ และคุณสามารถใช้กับประเภทvoid (*)(int, int)
ได้
หากคุณต้องการเข้าถึงสมาชิกที่ไม่คงที่ในคลาสของคุณ และคุณจำเป็นต้องยึดติดกับตัวชี้ฟังก์ชันเช่นเนื่องจากฟังก์ชันนี้เป็นส่วนหนึ่งของอินเทอร์เฟซ C ตัวเลือกที่ดีที่สุดของคุณคือส่งต่อvoid*
ไปยังฟังก์ชันโดยใช้ตัวชี้ฟังก์ชันและเรียกใช้ สมาชิกของคุณผ่านฟังก์ชั่นการส่งต่อซึ่งรับวัตถุจากvoid*
แล้วเรียกใช้ฟังก์ชันสมาชิก
ในอินเทอร์เฟซ C ++ ที่เหมาะสมคุณอาจต้องการดูว่าฟังก์ชันของคุณใช้อาร์กิวเมนต์ที่เป็นเทมเพลตสำหรับอ็อบเจ็กต์ฟังก์ชันเพื่อใช้ประเภทคลาสโดยพลการ หากมีการใช้อินเตอร์เฟซที่เป็นที่พึงปรารถนาเทมเพลตที่คุณควรจะใช้สิ่งที่ต้องการstd::function<void(int, int)>
: คุณสามารถสร้างวัตถุฟังก์ชั่น callable std::bind()
เหมาะสมสำหรับเหล่านี้เช่นการใช้
วิธีการประเภทปลอดภัยโดยใช้อาร์กิวเมนต์แม่แบบสำหรับประเภทคลาสหรือเหมาะสมstd::function<...>
จะดีกว่าการใช้void*
อินเทอร์เฟซเนื่องจากจะลบโอกาสที่จะเกิดข้อผิดพลาดเนื่องจากการแคสต์ผิดประเภท
เพื่อชี้แจงวิธีใช้ตัวชี้ฟังก์ชันเพื่อเรียกใช้ฟังก์ชันสมาชิกนี่คือตัวอย่าง:
// the function using the function pointers:
void somefunction(void (*fptr)(void*, int, int), void* context) {
fptr(context, 17, 42);
}
void non_member(void*, int i0, int i1) {
std::cout << "I don't need any context! i0=" << i0 << " i1=" << i1 << "\n";
}
struct foo {
void member(int i0, int i1) {
std::cout << "member function: this=" << this << " i0=" << i0 << " i1=" << i1 << "\n";
}
};
void forwarder(void* context, int i0, int i1) {
static_cast<foo*>(context)->member(i0, i1);
}
int main() {
somefunction(&non_member, 0);
foo object;
somefunction(&forwarder, &object);
}