C++ 类的成员函数指针 ( function bind )

一、概述

在 C++ 中,类的成员函数和普通函数的定义形式不同,因为它们需要指定关联的类。类的成员函数指针是指向类的成员函数的指针。使用类的成员函数指针可以让我们将一个特定的成员函数与一个对象分离开来,这样我们就可以在任意时间和任意对象上调用这个成员函数。

本文将介绍 C++ 中类的成员函数指针的用法和实际应用,包括定义和使用成员函数指针、使用 std::bind 绑定成员函数和对象、使用类成员函数指针作为回调函数等方面的内容。

二、类的成员函数指针的定义和使用

定义类成员函数指针的语法如下:

```

return-type (class-name::*pointer-name)(parameter-list);

```

其中,return-type 是成员函数的返回类型,class-name 是类名,pointer-name 是成员函数指针的名称,parameter-list 是成员函数的参数列表。

例如,定义一个指向成员函数 strLength() 的指针:

```

class String {

public:

int strLength(const char* str) const;

};

int (String::*pStrLength)(const char*) const;

pStrLength = &String::strLength;

```

在上面的代码中,pStrLength 是一个指向 String 类成员函数 strLength() 的指针。在这里,&String::strLength 是成员函数的地址,它被赋值给了 pStrLength。

使用类的成员函数指针可以在任意对象上调用该成员函数,方法如下:

```

String str;

const char* s = "Hello, World!";

int len = (str.*pStrLength)(s);

```

在上面的代码中,我们定义了一个 String 对象 str 和一个字符串 s,然后通过成员函数指针 pStrLength 调用了 strLength() 方法,并将返回值赋值给 len。

需要注意的是,调用类的成员函数时必须显式指定对象的地址,因为类成员函数是与对象相关联的函数。

三、使用 std::bind 绑定成员函数和对象

使用类的成员函数指针可以在任意对象上调用该成员函数,但是它需要手动指定对象的地址,并且不方便在参数列表中传递其他参数。为了解决这个问题,我们可以使用 std::bind 绑定成员函数和对象,并将绑定后的函数对象传递给其他函数。

std::bind 是一个函数模板,它可以将一个函数和一些参数绑定起来,并返回一个新的可调用对象。例如,我们可以使用 std::bind 绑定一个成员函数和对象:

```

// 定义类和成员函数指针

class String {

public:

int strLength(const char* str) const;

};

int (String::*pStrLength)(const char*) const = &String::strLength;

// 使用 std::bind 绑定成员函数和对象

String str;

const char* s = "Hello, World!";

auto boundFunc = std::bind(pStrLength, &str, s);

// 调用绑定后的函数

int len = boundFunc();

```

在上面的代码中,我们使用 auto 关键字定义了一个名为 boundFunc 的变量,并通过 std::bind 绑定了成员函数指针 pStrLength、对象 str 和字符串 s。然后,我们使用 boundFunc() 调用了绑定后的函数,并将返回值赋值给 len。

绑定函数的返回类型是一个函数对象,因此可以像普通函数一样调用它,并将返回值存储在变量中。

除了成员函数和对象,我们还可以通过 std::bind 绑定其他参数,例如:

```

// 定义类和成员函数指针

class String {

public:

void print(const char* str, int len) const;

};

void (String::*pPrint)(const char*, int) const = &String::print;

// 使用 std::bind 绑定成员函数、对象和参数

String str;

const char* s = "Hello, World!";

auto boundFunc = std::bind(pPrint, &str, s, 5);

// 调用绑定后的函数

boundFunc();

```

在上面的代码中,我们通过 std::bind 绑定了成员函数指针 pPrint、对象 str、字符串 s 和整数 5。然后,我们使用 boundFunc() 调用了绑定后的函数,这样成员函数 print() 就会输出字符串 s 的前 5 个字符。

四、使用类成员函数指针作为回调函数

类成员函数指针还可以用作回调函数,用于实现事件处理和消息传递等功能。例如,我们可以定义一个回调函数类 Callback,该类有一个成员函数指针和一个执行回调的方法:

```

template

class Callback {

public:

Callback(T* obj, int (T::*memberFunc)(const char* str))

: m_obj(obj), m_memberFunc(memberFunc)

{}

void invoke(const char* str) {

(m_obj->*m_memberFunc)(str);

}

private:

T* m_obj;

int (T::*m_memberFunc)(const char* str);

};

```

在上面的代码中,Callback 类的构造函数接受一个对象和一个成员函数指针,并将它们存储在类的成员变量中。invoke() 方法接受一个字符型指针参数,并调用成员函数指针 m_memberFunc,并将对象指针 m_obj 作为参数传递给它。

接下来,我们可以使用 Callback 类来创建一个回调对象,并在需要时调用它:

```

class String {

public:

String(Callback* callback)

: m_callback(callback)

{}

int strLength(const char* str) const {

int len = std::strlen(str);

m_callback->invoke(str);

return len;

}

private:

Callback* m_callback;

};

class Logger {

public:

int onStringLength(const char* str) {

std::cout << "String length = " << std::strlen(str) << std::endl;

return 0;

}

};

int main() {

Logger logger;

Callback callback(&logger, &Logger::onStringLength);

String str(&callback);

const char* s = "Hello, World!";

int len = str.strLength(s);

return 0;

}

```

在上面的代码中,我们定义了一个 Logger 类和一个 String 类,并在 String 类的构造函数中创建了一个 Callback 对象,并将其传递给 strLength() 方法。在 strLength() 方法中,我们调用了成员函数指针,然后调用了回调对象的 invoke() 方法。

在 main() 函数中,我们先创建了一个 Logger 对象 logger,并利用它创建了一个 Callback 对象 callback。然后,我们创建了一个 String 对象 str,并将 callback 对象传递给它的构造函数。最后,我们调用 strLength() 方法,并将返回值赋值给 len。在这个过程中,每当 strLength() 方法调用了成员函数 strLength() 时,Logger 类的成员函数 onStringLength() 就会被调用,并打印字符串的长度。

以上是本文的内容,通过本文的介绍,相信大家对 C++ 中类的成员函数指针有了更深入的了解,并知道如何使用类的成员函数指针来实现一些常见的功能。希望对大家有所帮助。 如果你喜欢我们三七知识分享网站的文章, 欢迎您分享或收藏知识分享网站文章 欢迎您到我们的网站逛逛喔!https://www.37seo.cn/

点赞(55) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部