类对象的成员函数有时可以当作一般的 ANSI C 函数一样处理。正如可以声明指向对象数据成员的一般指针一样,也可以声明指向对象成员函数的指针,然后通过该指针间接调用该函数。请看例1:
这种表示法有点讨厌。也许这就是一些程序员避免使用它的原因。指针 fp 用来调用类 Example 的两个不同的函数。同一指针可以调用不同的成员函数,但这些成员函数必须接收同样数目和类型的参数,返回同样的类型的值。如果成员函数需要参数,这种指针声明方法有些变化,如下面的例2:
上述代码给出了三种通过指针调用函数的方法。还有一个更大的变化:函数调用可以与对象指针连用。下面是类 Example 的例子:
不管传值还是传地址方式,调用非静态成员函数时都必须与具体的类的对象联系起来。静态成员函数有所不同,声明静态成员函数指针的 方法也有不同。不能用对象或对象的指针调用静态成员。如下面例3:
例1 使用成员函数指针 class Example{ long value; int time; public: long get_value(){return value;} long get_time(){return time + value;} }; int main() { long (Example::*fp)() = &Example::get_value; Example e; //间接调用 Example::get_value() long v = (e.*fp)(); //间接调用 Example::get_time()
fp = &Example::get_time;
long t = (e.*fp)();
return 0; }
这种表示法有点讨厌。也许这就是一些程序员避免使用它的原因。指针 fp 用来调用类 Example 的两个不同的函数。同一指针可以调用不同的成员函数,但这些成员函数必须接收同样数目和类型的参数,返回同样的类型的值。如果成员函数需要参数,这种指针声明方法有些变化,如下面的例2:
例2 指向带参数的成员函数指针 #include class Example{ long value; char name[30]; public: long set_value(long v) { value = v; return value; } long set_name(char* str) { strcpy(name,string); return name; } }; int main() { long (Example::*fp)(long) = &Example::set_value; Example e; //间接调用 Example::set_value() long new_value = 5; long v = (e.*fp)(new_value); //间接调用 Example::set_name() char* (Example::*fp1)(char*) = &Example::set_name; char* url ="dozb.blogchina.com"; char* new_name = (e.*fp1)(url); new_name = (e.*fp1)("dozb"); return 0; }
上述代码给出了三种通过指针调用函数的方法。还有一个更大的变化:函数调用可以与对象指针连用。下面是类 Example 的例子:
int main() { //声明一个对象 Example example; //声明一个指针指向它 Example * e = &example; //使用指向对象的指针 long (Example::*fp)(long) = &Example::set_value; long v = (e->*fp)(219); return 0; }
不管传值还是传地址方式,调用非静态成员函数时都必须与具体的类的对象联系起来。静态成员函数有所不同,声明静态成员函数指针的 方法也有不同。不能用对象或对象的指针调用静态成员。如下面例3:
例3 指向静态成员函数的指针 class StaticExample { public: static int foo(); static int woo()(; }; int value; //定义一个全局变量 int StaticExample::foo() { return value;//记住静态成员函数不能访问类数据成员,因为它们没有 this 指针 } int StaticExample::foo() { return 3; } int main() { int (*fp) = &StaticExample::foo; (*fp)(); fp = &StaticExample::woo; (*fp)(); }