乐趣区

C指针与成员

先看一个例子:
// 统一的接口

include <iostream>

using namespace std;

struct Point{

int plus(double x, double y){return x + y;}
int minus(double x, double y){return x - y;}
int mul(double x, double y){return x*y;}
int div(double x, double y){return x/y;}

};

int oper(Point & point, int (Point::*pfun)(double x, double y),

     double x, double y){return (point.*pfun)(x, y);

}

int main()
{

Point pt;
int (Point::*pfun)(double, double);
pfun = &Point::plus;
cout<<oper(pt, pfun, 10, 20);
pfun = &Point::minus;
cout<<oper(pt, pfun, 10, 20);
return 0;

}

再看一个例子:
// 更加隐蔽的接口

include <iostream>

using namespace std;

class Widget{
public:

Widget(){pf[0] = &Widget::f;
    pf[1] = &Widget::g;
    pf[2] = &Widget::h;
    pf[3] = &Widget::i;
}
int getCount(){return cnt;}
void select(int val, int sec){if(sec<0 && sec>3)
        return;
    (this->*pf[sec])(val);
}

private:

void f(int val){cout<<"void f()"<<val<<endl;
}
void g(int val){cout<<"void g()"<<val<<endl;
}
void h(int val){cout<<"void h()"<<val<<endl;
}
void i(int val){cout<<"void i()"<<val<<endl;
}

enum{cnt = 4};
void (Widget::*pf[4])(int);

};

int main()
{

Widget w;
w.select(100, 2);
return 0;

}

/指向静态成员的指针/
// 指向静态成员的指针的定义和使用与普通指针相同, 在定义时无须和类相关联
// 在使用时也无需和具体对象相关联

// 声明 < 数据类型 >*< 指针名 >
// 初始化 < 数据类型 >*< 指针名 > [=& < 类名 >::< 静态数据成员 >]
// 解引用 (*< 指向静态数据成员的指针 >)

// 声明 < 数据类型 >(*< 指针名 >)(< 参数列表 >)
// 初始化 < 数据类型 >(*< 指针名 >)(< 参数列表 >) [=&< 类名 >::< 静态成员函数 >]
// 解引用 (*< 指向静态成员函数的指针 >)(< 参数列表 >
// 和普通函数指针, 唯一的区别是: 在初始化时,&classname::member, 要加上类名限定

include <iostream>

using namespace std;

class A{
public:

static void dis();
static int data;

};

void A::dis(){

cout<<data<<endl;

}

int A::data = 100;

int main()
{

int *pa = &A::data;
cout<<*pa<<endl;    //100

void (*pf)() = A::dis;
pf();   //100
return 0;

}

/指向类成员函数的指针 /
// 定义一个指向非静态成员函数的指针必须在三个方面与其指向的成员函数保持一致
// 参数列表相同, 返回类型要相同, 所属的类型(类名) 要相同
// 由于类不是运行时存在的对象, 因此, 在使用这类指针时, 需要首先指定类的一个对象
// 然后, 通过对象来引用指针所指的成员
// 声明 < 数据类型 >(< 类名 >::*< 指针名 >)(< 参数列表 >)
// 初始化 < 数据类型 >(< 类名 >::*< 指针名 >)(< 参数列表 >) [=&< 类名 >::< 非静态成员函数 >]
// 解引用 (< 类对象名 >.*< 指向非静态成员函数的指针 >)(< 参数列表 >)
// (< 类对象指针 >->*< 指向非静态成员函数的指针 >)(< 参数列表 >)

include <iostream>

using namespace std;

class Student{
public:

Student(string n, int nu): name(n), num(nu){}
void dis(){cout<<"name:"<<name<<"num:"<<num<<endl;}

private:

string name;
int num;

};

int main()
{

Student s("zhangtong", 30);
Student s2("lidan", 26);
Student *ps = new Student("zhaolanni", 35);

void (Student::*pf)() = &Student::dis;

(s.*pf)();  //name: zhangtong num: 30
(s2.*pf)(); //name: lidan num: 26
(ps->*pf)();    //name: zhaolanni num: 35
return 0;

}

/指向类数据成员的指针/
// 是类层面的指针, 而不是对象层面的指针
// 跟普通意义上的指针用法有很大的差别
// 定义格式上, 必须有类别限定 type className::*pointName
// 初始化, 也必须有类名限定 &className::member
// 并且定义的指针, 只有通过具体的对象或对象指针才可以调用

// 声明 < 数据类型 >< 类名 >::*< 指针名 >
// 初始化 < 数据类型 >< 类名 >::*< 指针名 > [=& < 类名 >::< 非静态数据成员 >]
// 解引用 < 类对象名 >.< 指向非静态数据成员的指针 > < 类对象指针 >->< 指向非静态数据成员的指针 >

include <iostream>

using namespace std;

class Student{
public:

Student(string n, int nu): name(n), num(nu){}

string name;
int num;

};

int main()
{

Student s("zhangtong", 29);
Student s2("lisa", 43);

string Student::*pn = &Student::name;
cout<<s.*pn<<endl;  //zhangtong
cout<<s2.*pn<<endl; //lisa

Student *ps = new Student("zhaoliu", 35);
cout<<ps->*pn<<endl;    //zhaoliu

return 0;

}

退出移动版