C++ 中指向成員函式的函式指標

Jay Shaw 2023年1月30日 2022年7月18日
  1. 在 C++ 中實現指向成員函式的函式指標
  2. 在 C++ 中附加指向成員函式的指標
  3. 在 C++ 中不使用指標符號呼叫指向成員函式的指標
  4. 在 C++ 中給出與函式指標相同的類的方法
  5. 在 C++ 中使用字串命令指向成員函式的函式指標
C++ 中指向成員函式的函式指標

當使用程式語言建立變數時,機器必須將其值儲存在計算機記憶體中。機器分配一些記憶體給這個變數,無論是否為空。

通常需要位置而不是變數的值。在此期間,可以通過指標獲取這些值。

此外,與引用記憶體地址相比,C++ 中的指標還可用於指向一段程式碼,例如函式。這些被稱為函式指標,提高了程式碼的效率。

本文的示例將清楚地展示如何在類中使用函式指標來使指標指向 C++ 中的成員函式。

在 C++ 中實現指向成員函式的函式指標

有兩種方法可以做到這一點。

  1. 建立一個指向成員函式的函式指標。
  2. 僅使用函式指標的名稱呼叫方法。

在 C++ 中附加指向成員函式的指標

使用指標函式需要以下步驟。

  1. 具有返回型別的引數化函式 - void。
  2. 型別轉換指標變數。
  3. 將指標變數分配給方法。
  4. 使用指標呼叫主函式內部的引數化函式的方法呼叫。

為程式內部的輸入/輸出功能匯入標準 stdio 包。函式 display 使用引數 var1 宣告,具有整數資料型別。

void display(int var1)
{
    printf("The variable holds value = %d\n", var1);
}

display 方法中,會列印 var1

變數 ptr_method 在主函式中具有資料型別 void。必須注意的是,void 可以用作 c++ 中的資料型別,但它充當佔位符,並不真正代表一種資料型別。

然後為宣告的指標變數提供一個整數引數,如下所示:

void (*ptr_method)(int)

ptr_method 有一個整數引數。這將在呼叫 ptr_method 時將值傳遞給成員方法。

因為使用任何其他資料型別會導致編譯器出現不正確的轉換錯誤,所以指標函式 ptr_method 已被賦予 void 資料型別。

使用下面的語法將函式指標分配給程式開始時宣告的函式。使用以下語法使指標指向函式 display

ptr_method = &display;

最後,使用提供為 "65" 的整數引數呼叫指標函式。

程式碼:

#include <stdio.h>

// This method has a parameter int and a return type which is void

void display(int var1)
{
    printf("The variable holds value = %d\n", var1);
}

int main()
{
    void (*ptr_method)(int);
    ptr_method = &display;

    (*ptr_method)(65);

    return 0;
}

輸出:

The variable holds value = 65

在 C++ 中不使用指標符號呼叫指向成員函式的指標

本例中使用的程式與上述程式相同,只是函式呼叫不同。這裡,使用變數名呼叫指標變數,不包括星號 (*)。

該程式按預期工作,因為當函式指標指向一個方法時,可以使用指標和變數形式訪問儲存在其中的方法的記憶體地址。例如,當定義函式指標 ptr_method 時,函式 display 賦值是通過直接使用變數名來完成的,而不是像前面示例中那樣在變數名前新增&

在函式呼叫時,直接呼叫函式指標 ptr_method,不使用指標符號(*)並傳遞值 54

void (*ptr_method)(int);
    ptr_method = display;

    ptr_method(54);

程式碼:

#include <stdio.h>

void display(int var1)
{
    printf("The variable holds value = %d\n", var1);
}

int main()
{
    void (*ptr_method)(int);
    ptr_method = display;

    ptr_method(54);

    return 0;
}

輸出:

The variable holds value = 54

在 C++ 中給出與函式指標相同的類的方法

本例中使用的程式與其他兩個程式類似。但是在這裡,指標是一種方法,而其他兩個程式中的工作是由簡單的指標變數處理的。

建構函式類 assgnPtr 由兩個公共成員建立 - 一個 char 方法 foo 和另一個 char 方法,它是一個函式指標 ptr。這兩種方法如下面的語法所示,從語法的最後一行可以清楚地看出,它指向函式指標的類 assgnPtr

    public:
        char foo();
        char (assgnPtr::*ptr)();

在宣告公共方法後,函式 foo() 提供了一個返回 f。這意味著當呼叫函式指標時,程式呼叫函式 foo 並列印返回的任何內容。

在 main 方法中宣告瞭一個名為 var1 的變數。此變數用作類物件。

這是因為作為成員函式的函式指標具有在沒有來自同一類的物件的情況下無法訪問的缺點。成員函式按以下語法分配給指標變數。

int main() {
    assgnPtr var1;
    var1.ptr = &assgnPtr::foo;

指標 ptr 與物件類 var1 一起使用,並分配給方法 foo。作為建構函式,該方法必須使用::符號分配,表明該函式是類 assgnPrt 的成員方法。

最後,需要列印結果。

printf("%c\n",(var1.*(var1.ptr))());

它可能會讓讀者感到不安,因為它理解起來非常複雜。所以需要把它分解成小塊才能清楚地理解。

var1.ptr 是指向類 assgnPtr 的成員函式的指標。但是當使用 *(var1.ptr) 時,它會變成指標引用,而列印 *(var1.ptr) 不能直接使用,因為 ptr 不在範圍內。

出於這個原因,它需要與類物件 var1 繫結為 var1.*(var1.ptr)

最後,(var1.*(var1.ptr))() 呼叫不帶引數的方法。print 語句列印使用函式指標呼叫方法時返回的值。

完整原始碼:

#include <iostream>

class assgnPtr {
    public:
        char foo();
        char (assgnPtr::*ptr)();
};

char assgnPtr::foo() {
    return 'f';
}

int main() {
    assgnPtr var1;
    var1.ptr = &assgnPtr::foo;
    printf("%c\n",(var1.*(var1.ptr))());
}

輸出:

f

在 C++ 中使用字串命令指向成員函式的函式指標

在這個例子中,程式使用字串命令來分配函式指標。核心概念類似,只是成員方法使用關係運算子來檢查和分配指標。

該程式使用兩個匯入函式,用於 i/oiostream 和用於字串命令的 string。建立了一個構造器類 assgnPtr2

有兩個私有成員 displaypass_value 和一個公共成員 func_ptr,它將是函式指標。

私有成員 pass_value 具有三個引數 - 資料型別字串的變數 x 和 y,以及函式原型 foo。函式原型宣告引數 foo 將是一個指向函式的指標。

分配指標時,方法 display 將列印一條語句。方法 func_ptr 呼叫方法 pass_value 並將 xy 的值作為引數傳遞,並使用&符號作為函式原型的引數附加方法 display

最後,在方法 pass_value 中,使用關係運算子 == 比較傳遞的 x 和 y 的值。如果 x 和 y 的值都匹配,則 if 語句將指標 foo 分配給方法。

在 main 函式中,建立了一個類物件 var。使用這個物件,方法 func_ptr 被呼叫。

完整原始碼:

#include <iostream>
#include <string>

class assgnPtr2
{
    public:
        void func_ptr();
    private:
        void display();
        void pass_value(std::string x, std::string y, void (assgnPtr2::*foo)());
};

void assgnPtr2::display()
{
    std::cout<< "Pointer Assigned\n";
}

void assgnPtr2::func_ptr()
{
    pass_value("h","h", &assgnPtr2::display);
}

void assgnPtr2::pass_value(std::string x, std::string y, void (assgnPtr2::*foo)())
{
    if(x==y)
    {
        (this->*foo)();
    }
}

int main()
{
    assgnPtr2 var;
    var.func_ptr();
    return 0;
}

輸出:

Pointer Assigned

相關文章 - C++ Pointer