#include <iostream>
using namespace std;
class Test {
public:
Test():x(0), y(0)
{
cnt++;
}
int x;
int y;
void print() const;
static int cnt;
static void print_s(); //静态成员函数不能够设置为const函数 ( static member function cannot have cv qualifier??? cv 限定符 即 const and volatile)
};
int Test::cnt = 0; //静态成员变量的初始化
void Test::print_s()
{
cout<<cnt<<" object(s) has(have) been created"<<", visited by print_s function"<<endl;
}
void Test::print() const
{
cout<<"x = "<<x<<" y = "<<y<<endl;
}
int main()
{
int Test::*ptr; //声明指向类非静态成员变量的指针
void (Test::*print_p)() const; //声明指向类非静态成员函数的指针
print_p = &Test::print; //赋值
ptr = &Test::x; //赋值
Test a;
a.*ptr = 1; //调用
(a.*print_p)(); //调用,前面的括号不能掉(运算符的优先级)
int *ptr_1 = &Test::cnt; //声明和初始化指向类静态成员变量的指针
cout<<*ptr_1<<" object(s) has(have) been created"<<", visited by pointer"<<endl; //通过指针访问静态成员变量
Test::print_s(); //通过静态成员函数访问静态成员变量
return 0;
}
用一个实际代码来说明。
- class A
- {
- public:
- static void staticmember() { cout<<"static"<<endl; } //static member
- void nonstatic() { cout<<"nonstatic"<<endl; } //nonstatic member
- virtual void virtualmember() { cout<<"virtual"<<endl; }; //virtual member
- };
- int main()
- {
- A a;
- //static成员函数,取得的是该函数在内存中的实际地址,而且因为static成员是全局的,所以不能用A::限定符
- void(*ptrstatic)()=&A::staticmember;
- //nonstatic成员函数 取得的是该函数在内存中的实际地址
- void(A::*ptrnonstatic)()=&A::nonstatic;
- //虚函数取得的是虚函数表中的偏移值,这样可以保证能过指针调用时同样的多态效果
- void(A::*ptrvirtual)()=&A::virtualmember;
- //函数指针的使用方式
- ptrstatic();
- (a.*ptrnonstatic)();
- (a.*ptrvirtual)();
- }
可以参考《C++ Primer(3rd)》第532页13.6指向类成员的指针一节~
1.一个指向外部函数的指针声明为:
- void(*pf)(char*,constchar*);
- void strcpy(char* dest,constchar* source);
- pf=strcpy;
2.一个指向类A成员函数的指针声明为:
- void(A::*pmf)(char*,constchar*);
声明的解释是:pmf是一个指向A成员函数的指针,返回无类型值,函数带有二个参数,参数的类型分别是char * 和 const char *。除了在星号前增加A:: ,与声明外部函数指针的方法一样。
3.给成员指针赋值的方法是将函数名通过指针符号&赋予指针名。
如下所示:
-
- class A
- {
- public:
- void strcpy(char*,constchar*);
- void strcat(char*,constchar*);
- };
- pmf =&A::strcpy;
- 比较pmf=&A::strcpy与pmf=A::strcpy,为什么pmf=A::strcpy会报错!
- 函数名并不是函数地址的代表,这种误解与数组名就是指针一样犯了相同的错误。函数名是函数实体的代表,不是地址的代表,当然,你马上就会有疑问,平时我们不都是把函数名作为函数的地址吗?是的,我可以告诉你,函数名可以作为函数的地址,但是,绝大多数人都忽略了一个条件,从函数到指针的隐式转换是函数名在表达式中的行为,就是说,这个转换仅在表达式中才会发生,这仅是函数名众多性质中的一个,而非本质,函数名的本质就是函数实体的代表。到了C++,由于C++规定,非静态成员函数的左值不可获得,因此非静态成员函数不存在隐式左值转换,即不存在像常规函数那样的从函数到指针的隐式转换,所以必须在非静态成员函数前使用&操作符才能获得地址。
转载处:
https://www.cnblogs.com/rocklee25/p/7401158.html