c++的成員函數指針

假設目前有一個類

class Object {
public:
    void function() const {
    }

    void function2() const {
    }

};

Object::function是 "成員函數"

&Object::function是 "成員函數的地址"

現在有一種新的數據類型 void(Object::*)()叫做成員函數指針,它能夠被賦值"成員函數的地址"。

"成員函數指針"要指定物件Object、返回值void、形參()、函數修飾詞 如const,如此該指針能指到準確的函數,如果有函數這四個都一樣,那這個指針就可以指到它。
 

    void (Object:: * funcPtr)() const = &Object::function;
//數據類型 void (Object3:: * )() const
//變量名稱 funcPtr
//初始化的值  &Object::function
   //另外一個返回值 物件 形參 函數修飾詞 都一樣的函數 能夠賦值給funcPtr 
 funcPtr = &Object::function2;
//要使用成員函數指針,需要一個成員函數指針裡的函數一樣的類,和.*運算符。
//成員訪問運算符.* 
//指針到成員訪問運算符->* 
    Object obj;
    Object* objPtr;
    (obj.*funcPtr)();  // 输出: Show method from Object
    (objPtr->*funcPtr)();

由於是一種數據類型,所以可以在任何地方宣告出來,如果有物件有被初始化過的成員函數指針,那這個物件就會有能力去調用這個函數。
 

class B {
public:
    void bFunction() const {
        std::cout << "Calling B::bFunction" << std::endl;
    }
};


class A {
public:
    // 定义一个指向 B 类成员函数的指针
    void (B::* bFuncPtr)() const = nullptr;

    // 方法,允许 A 对象调用 B 的成员函数
    void callBFunction(const B& b) const {
        if (bFuncPtr != nullptr) {
            (b.*bFuncPtr)();  // 使用成员函数指针调用 B 的成员函数
        }
    }
};

void funcPart14()
{
    A a;
    B b;
    a.bFuncPtr = &B::bFunction;
    a.callBFunction(b);
    //或者說
    (b.* (a.bFuncPtr))();
    
}

像在上方的代碼中,在A裡面宣告了一個變量,這樣A能使用B的函數。


這東西還能和模板一起用,這樣可以通用化返回值跟形參,更加強大。

class Object4 {
public:
    void display() const {
        std::cout << "Displaying Object4" << std::endl;
    }

    int count(int n) const {
        return n;
    }
};

// 模板类,用于持有任意类型成员函数的指针
template<typename ReturnType, typename... Args> //Args是數據類型
class MemberFuncPtr {
public:
    ReturnType(Object4::* funcPtr)(Args...) const;  // 成员函数指针

    // 构造函数,用于初始化成员函数指针
    MemberFuncPtr(ReturnType(Object4::* ptr)(Args...) const) : funcPtr(ptr) {}

    // 调用成员函数的方法
    ReturnType invoke(const Object4& obj, Args... args) const {
        return (obj.*funcPtr)(args...);
    }
};


void funcPart16()
{
    Object4 obj;
    MemberFuncPtr<void> displayPtr(&Object4::display);
    displayPtr.invoke(obj);  // 调用 Object4 的 display 方法

    MemberFuncPtr<int, int> countPtr(&Object4::count);
    int result = countPtr.invoke(obj, 42);  // 调用 Object4 的 count 方法,并传入参数 42
    std::cout << "Count result: " << result << std::endl;
}

->*是可以重載的,不過.*不能重載,不過未來我應該會寫一個c++ operator overloading的文章,這裡不講。

既然他是數據類型,那應該有類型轉換,不過好像非常侷限,沒什麼用。

class Object3 {
public:
    void display() const {
        std::cout << "Display method from Object3" << std::endl;
    }
    void show() const {
        std::cout << "Show method from Object3" << std::endl;
    }
};


void funcPart15()
{
    // 创建指向 Object3::display 的成员函数指针
    void (Object3:: * funcPtr)() const = &Object3::display;

    // 进行类型转换至指向 Object3::show 的成员函数指针
    funcPtr = (void(Object3::* )() const) &Object3::show;
    funcPtr = & Object3::show;
    //這兩行是一樣的

    // 使用转换后的指针调用函数
    Object3 obj;
    Object3* objPtr;
    (obj.*funcPtr)();  // 输出: Show method from Object3
    (objPtr->*funcPtr)();
    //error 不能這樣做
    //A a;
    //(a.*funcPtr)();
}

總結一下,

使用上來說,就是

返回值(物件::* 變量 )(形參) 修飾詞;

返回值(物件::* 變量 )(形參) 修飾詞 = &物件::函數。

該函數的 返回值 物件 形參 修飾詞 都要和成員函數指針宣告的 返回值(物件::* 變量 )(形參) 修飾詞一樣。(或者用模板)

然後,使用

(物件.*變量)(形參);

(物件指針->*變量)(形參);來調用函數

然後加上模板就變成,這個指針可以指向很大範圍的函數。

ReturnValue (物件::* 變量) (Arg...)函數修飾詞;

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值