首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

C++ 實現 .NET 風格委托:類型安全的回調機制

     編輯:VC 教學

.NET 中的委托是一種類型安全的函數指針,廣泛用於事件處理。在標準 C++ 中實現同樣功能並非易事,特別是對非靜態成員函數的支持。本文展示一種基於**函數對象**與**模板技術**的方案,支援靜態成員函數、非靜態成員函數及全局函數的統一回調,且嚴格保證類型安全。

什麼是委托?

委托是一個持有方法引用的類,擁有自己的簽名(返回類型、參數類型、個數),只能綁定匹配簽名的方法。它實現了「發布-訂閱」模式:提供委托的類無需知道具體有多少處理函數,只需調用委托,委托內部自動遍歷並調用所有已註冊的處理函數。

核心實現:函數對象

函數對象重載 operator(),使其調用語法與普通函數一致。首先定義一個基礎模板類,綁定對象指針與成員函數指針:

template <class T>
class Functor {
public:
    Functor(T* pObj, int (T::*pFunc)(int))
        : m_pObject(pObj), m_pFunction(pFunc) {}

    int operator()(int p) {
        return (m_pObject->*m_pFunction)(p);
    }

private:
    T* m_pObject;
    int (T::*m_pFunction)(int);
};

使用示例

class MyClass {
public:
    int Square(int p) { return p * p; }
};

void some_function() {
    MyClass theClass;
    Functor<MyClass> myFunc(&theClass, &MyClass::Square);
    int result = myFunc(5);  // result == 25
}

多態支援:引入抽象基類

為了在不知具體類型的情況下統一調用,定義一個純虛基類 FunctorBase,並令模板類繼承它:

class FunctorBase {
public:
    virtual int operator()(int) = 0;
    virtual ~FunctorBase() = default;
};

template <class T>
class TemplateFunctor : public FunctorBase {
public:
    TemplateFunctor(T* pObj, int (T::*pFunc)(int))
        : m_pObject(pObj), m_pFunction(pFunc) {}

    int operator()(int p) override {
        return (m_pObject->*m_pFunction)(p);
    }

private:
    T* m_pObject;
    int (T::*m_pFunction)(int);
};

現在可以編寫接受基類指針的通用函數:

int OperateOnFunctor(int i, FunctorBase* pFunc) {
    return pFunc ? (*pFunc)(i) : 0;
}

實戰測試

class ClassA {
public:
    ClassA(int i) : m_Value(i) {}
    int FuncA(int i) { return m_Value - i; }
    int m_Value;
};

void test() {
    ClassA a(10), b(20);
    TemplateFunctor<ClassA> fa(&a, &ClassA::FuncA);
    TemplateFunctor<ClassA> fb(&b, &ClassA::FuncA);

    cout << OperateOnFunctor(3, &fa) << endl;  // 7
    cout << OperateOnFunctor(3, &fb) << endl;  // 17
}

設計優勢與局限

  • ✅ 類型安全:編譯期檢查簽名匹配;
  • ✅ 統一接口:基類指針屏蔽具體類型差異;
  • ✅ 支持非靜態成員函數:自動綁定 this 指針;
  • ⚠️ 簽名固定:本例僅演示 int(int),實際專案可用模板參數化返回值與參數;
  • ⚠️ 生命週期管理:需確保綁定對象在函數對象使用期間存活。

此模式是現代 C++(std::function、std::bind、Lambda)的雛形,理解其原理有助於深入掌握 C++ 回調機制的本質。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved