《C和C++代码精粹》——2.13 指向成员函数的指针

2.13 指向成员函数的指针

C和C++代码精粹
如果返调函数是某个类的成员函数将会怎样?获得指向类成员的指针与获得指向非成员实体的指针的方式相似,只存在很小的语法变化。例如,考虑下面类的定义:

class C
{
public:
   void f ( )  {cout << "C::f\n";}
   void g( )  {cout << "C::g\n";}
};

可以这样定义一个指向C类成员函数的指针:

void (C::*pmf) ( );  // pmf是指向C的成员函数的指针
                        //不带参数并且没有返回值

可以根据需要来初始化pmf使其指向不同的成员函数,如下面的程序所示:

main( )
{
   C c;
   void (C::*pmf) ( ) =&C::f;
   (c.*pmf) ( );
   pmf =&C:: g;
   (c.*pmf) ( );
}
//输出:
C::f
C::g

运算符调用了代表其左边操作数所指向的对象的成员函数。如果 cp 是一个指向 C 的指针,那么可以使用->运算符,就像:

( cp->*pmf ) ( );

由于C++定义运算符优先级的方式,所以圆括号是完全确认所调用的函数所必需的。请参见程序清单2.19(程序清单2.18菜单例子的指向成员函数指针的版本)。

程序清单2.19 举例说明对成员的指针

// menu2.cpp: 使用指向函数成员的指针
#include <iostream>
using namespace std;  

class Object
{
public:
    void retrieve() {cout << "Object::retrieve\n";}
    void insert() {cout << "Object::insert\n";}
    void update() {cout << "Object::update\n";}
    void process(int choice);  

private:
    typedef void (Object::*Omf)();
    static Omf farray[3];
};  

Object::Omf Object::farray[3] =
    {
        &Object::retrieve,
        &Object::insert,
        &Object::update
    };  

void Object::process(int choice)
{
    if (0 <= choice && choice <= 2)
        (this->*farray[choice])();
}  

main()
{
    int show_menu();    //你所提供的!
    Object o;  

    for (;;)
    {
        int choice = show_menu();
        if (1 <= choice && choice <= 3)
            o.process(choice-1);
        else if (choice == 4)
            break;
    }
}

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

时间: 2024-09-12 22:55:59

《C和C++代码精粹》——2.13 指向成员函数的指针的相关文章

vs2008下C++对象内存布局(6):指向成员函数的指针

Vs支持指向成员函数的指针,沿用上文中的类进行试验: class CParentA { public: int parenta_a; int parenta_b; public: virtual void parenta_f1() {this->parenta_a = 0x10;} virtual void parenta_f2() {this->parenta_a = 0x20;} public: void parenta_f3() {this->parenta_a = 0x30;}

《C和C++代码精粹》——1.4 函数原型

1.4 函数原型 C和C++代码精粹在C++中,函数原型不是可选的.事实上,在ANSI C委员会采用原型机制以前,它是为C++发明的.在你第一次使用函数前必须声明或定义每个函数,编译器将检查每个函数调用时正确的参数数目和参数类型.此外,在其应用时将执行自动转换.下列程序揭示一个在C中不使用原型时出现的普通错误. /* convert1.c */ #include <stdio.h> main( { dprint(123); dprint(123.0); return 0; } dprint(d

《C和C++代码精粹》——1.11 函数重载和函数模板

1.11 函数重载和函数模板 C和C++代码精粹程序清单1.4中的交换函数(swap)只有在交换整数时才有用.如果要交换两个任何系统预定义的数据类型中的对象该么办呢?C++允许定义多个同名函数,只要它们的特征不同.因此就可以为所有系统预定义的数据类型定义一个交换函数: void swap(char &,char &); void swap(int &,int &); void swap(long &,long &); void swap(float &

C++编程指向成员的指针以及this指针的基本使用指南_C 语言

指向成员的指针指向成员的指针的声明是指针声明的特例.使用以下序列来声明它们: [storage-class-specifiers] [cv-qualifiers] type-specifiers [ms-modifier] qualified-name ::* [cv-qualifiers] identifier [= & qualified-name :: member-name]; 声明说明符: 可选存储类说明符. 可选 const 和/或 volatile 说明符. 类型说明符:类型的名称

《C和C++代码精粹》导读

前言 C和C++代码精粹 本书适合于那些C和C++的职业程序员.假如你已熟悉这两种语言的语法和基本结构,这本书能够为你创建有效的.实用的程序提供实践性的指导.每一个代码范例或程序范例均标明行之有效的用法和技术,这些用法和技术对C/C++这两种重要编程语言的性能发挥起着重要的作用. 对于那些希望在工作中加强自身技术和提高效率的人来说,本书可以算是一本经验之谈.尽管目前人们对面向对象模式的推崇到了白热状态(本书也包括这方面的丰富内容),可是我没有理由不对C++的基础-C表示尊崇.我发现太多的程序开发

《C和C++代码精粹》——第 2 章 指针2.1 容易出错的编程

第 2 章 指针 C和C++代码精粹本文仅用于学习和交流目的,不代表异步社区观点.非商业转载请注明作译者.出处,并保留本文的原始链接. 2.1 容易出错的编程 C和C++代码精粹"分割违规" "访问违规" "可疑的指针转换" "不可移植的指针转换" "空指针赋值" 这些消息听起来熟悉吗?指针出错是C++程序员必须应付的最令人厌恶的错误.实际上,长时间以来指针和它所提供给开发者的原始功能已经成为人们对C主要的

《C和C++代码精粹》——2.12 指向函数的指针

2.12 指向函数的指针 C和C++代码精粹 一个指针可以指向函数也可以指向存储的对象.下面的语句声明fp是一个指向返回值为整型(int)的函数的指针: int(*fp)( ); *ftp的圆括号是必需的,没有它的语句 int *fp( ); 将fp声明为一个返回指向整型(int)指针的函数.这就是将星号与类型声明紧密相连的方式成为逐渐受人们欢迎的方式的原因之一. int fp(); //方式说明fp()返回一个指向整型的指针(int ) 当然,这种方式建议你通常应该每条语句只声明一个实体,否则

《C和C++代码精粹》——2.9 字符串数组

2.9 字符串数组 C和C++代码精粹有两种方式来描述C风格的字符串数组:(1)指针数组:(2)二维数组.程序清单2.13中的程序说明了第一种方式.内存分布如下: 程序清单2.13 用指向字符的指针数组来实现字符串 // array6.cpp:粗糙的数组 #include <iostream> #include <cstring> using namespace std; main() { char* strings[] = {"now","is&qu

《C和C++代码精粹》——2.6 const指针

2.6 const指针 C和C++代码精粹注意memcpy函数第二个参数中的const关键字.这个关键字告诉编译器此函数将不会改变source指向的任何值(除了强制类型转换).当把指针作为参数传递时,总是合适地使用const限定符是一个很好的习惯,它不仅可以防止你无意中错误的赋值,而且还可以防止在作为参数将指针传递给函数时可能会修改了本不想改变的指针所指向的对象的值.例如,如果在程序清单2.6中的声明是: const int i=7,j=8; 有可能因为下面这条语句而得到警告: swap(&i,