C++拾遗--类成员指针

C++拾遗--类成员指针

前言

类成员的类型与一般类型不同,那么类成员的指针类型自然与一般类型的指针有所区别。我们有必要来探讨下类成员指针的使用。

正文

类成员指针是指可以指向类的非静态成员的指针。它的类型包括了类类型和所指向的成员类型。一般而言,指针指向的是对象,而类成员指针指向的是类成员而非类对象。

需要指出,类成员指针不是可调用对象,要想通过类成员指针调用类成员,需结合类对象或类指针。静态类型成员属于类,类型与普通指针相似。

数据成员指针

一般的声明形式:

成员类型 classname::*p;

它的赋值形式:

p = &classname::类数据成员;

这里的取地址符&,是必须的。

#include <iostream>
using namespace std;
class Myclass
{
public:
	int a;
	const char c;
	Myclass(int a, int c) :a(a), c(c)
	{

	}
};
int main(void)
{
	int Myclass::*pa;
	pa = &Myclass::a;

	const char Myclass::*pc;
	pc = &Myclass::c;

	Myclass my(520, 'C'), *p = &my;
	cout << my.*pa << endl;
	cout << p->*pa << endl;
	cout << my.*pc << endl;
	cout << p->*pc << endl;
	cin.get();
	return 0;
}

运行

在这个例子中,我们定义了两个成员指针pa和pc。其中pc的声明必须加上const,否则,稍后的赋值会发生类型不匹配的错误。我们还定义了类的对象和指针,它们分别通过成员指针访问运算符.*和->*,对类成员指针进行访问。

函数成员指针

和数据成员指针类似,它的声明同样得指定类类型和函数成员类型。

返回类型 (classname::*pfun)(参数类型列表);

它的赋值形式:

pfun = &classname::类函数成员;

#include <iostream>
using namespace std;
class Compute
{
public:
	int add(int a, int b)
	{
		return a + b;
	}
	int sub(int a, int b) const
	{
		return a - b;
	}
};
int main(void)
{
	int (Compute::*pfun1)(int, int);
	pfun1 = &Compute::add;

	int (Compute::*pfun2)(int, int) const;
	pfun2 = &Compute::sub;

	Compute com, *p = &com;
	cout << (com.*pfun1)(100, 10) << endl;
	cout << (p->*pfun1)(100, 10) << endl;
	cout << (com.*pfun2)(100, 10) << endl;
	cout << (p->*pfun2)(100, 10) << endl;
	cin.get();
	return 0;
}

运行

这个例子就不多解释了。只说一句:访问限定符仍然有效,可在类外访问的数据和函数才可以使用类成员指针调用。

mem_fn

通过mem_fn对类函数成员指针进行包装,来返回一个可调用对象。使用时,包含头文件functional。

#include <iostream>
#include <functional>
using namespace std;
class Compute
{
public:
	Compute(int a, int b) :a(a), b(b)
	{

	}
	int add()
	{
		return a + b;
	}
	int sub() const
	{
		return a - b;
	}
private:
	int a;
	int b;
};
int main(void)
{
	Compute com(100, 10), *p = &com;
	auto fun1 = mem_fn(&Compute::add);
	cout << fun1(com) << endl;
	cout << fun1(p) << endl;
	auto fun2 = mem_fn(&Compute::sub);
	cout << fun2(com) << endl;
	cout << fun2(p) << endl;
	cin.get();
	return 0;
}

运行

由于add方法是参数是void的,所有调用时,只传递类对象fun(com)或指针fun(p)即可。

若成员方法是带参数的,该如何使用呢?看下面的代码:

#include <iostream>
#include <functional>
using namespace std;
class Compute
{
public:
	int add(int a, int b)
	{
		return a + b;
	}
	int sub(int a, int b) const
	{
		return a - b;
	}
};
int main(void)
{
	Compute com, *p = &com;
	auto fun1 = mem_fn(&Compute::add);
	cout << fun1(com, 100, 10) << endl;
	cout << fun1(p, 110, 10) << endl;
	auto fun2 = mem_fn(&Compute::sub);
	cout << fun2(com, 120, 10) << endl;
	cout << fun2(p, 130, 10) << endl;
	cin.get();
	return 0;
}

运行

这个示例显示了,若是带参数的,参数跟在类对象或类指针后面即可。

mem_fn会根据传入的参数类型,自动选择调用.*或->*:

Compute com, *p = &com;

auto fun = mem_fn(&Compute::add);

fun(com);  //传入对象,这一句会被解释成 auto padd = &Compute::add; (com.*padd)();

fun(p);    //传入指针,这一句会被解释成 auto padd = &Compute::add; (p->*padd)();

bind

使用函数适配器bind,绑定类函数成员,返回可调用对象。

bind函数绑定中,已经有了详细介绍。

本专栏目录

所有内容的目录

时间: 2024-10-11 22:01:22

C++拾遗--类成员指针的相关文章

C++ Primer 学习笔记_103_特殊工具与技术 --类成员指针

特殊工具与技术 --类成员指针 成员指针可以做到:获得特定成员的指针,然后从一个对象或别的对象获得该成员.成员指针应该包含类的类型以及成员的类型. 一.声明成员指针 测试类: class Screen { public: typedef std::string::size_type index; char get() const; char get(index ht,index wd) const; private: std::string contents; index cursor; ind

类成员指针——偏移量

成员指针只是记录一个成员的偏移量,而非地址,因为类中没有地址,选择一个类的成员只是意味着在类中偏移,只有把这个偏移和具体对象的首地址结合,才能得到实际地址. 成员指针并不指向一个具体的内存位置,它指向的是一个类的特定成员,而不是指向一个特定对象的特定成员,最直接的理解是将其理解为一个偏移量.这个偏移量适用于某一类A的任何对象,换言之,如果一个A类对象的成员a距离起点的偏移量是4,那么任何其他A类对象中,a的偏移都是4字节. 类对象访问其成员时,是根据该成员在类中的偏移量来访问的. 类成员指针,可

[C++ primer]类成员指针

1.声明成员指针 有时我们希望直接获取成员的指针,然后从一个对象或别的对象获得该成员,这时就需要用到成员指针.成员指针,包含类的类型以及成员的类型. 成员指针只针对类的非static成员.static类成员不是任何对象的组成部分,所以不需要特殊语法来指向static成员,static成员指针是普通指针. 注:它指向的是一个类的特定成员,而不是指向一个特定对象里的特定成员. 成员指针的定义格式:成员类型 类名::*指针名=&类名::成员名; 成员函数指针的定义格式: 成员函数返回类型 类名::*指

C++ Primer 笔记——类成员指针

1.当我们初始化一个成员指针或为成员指针赋值时,该指针并没有指向任何数据.成员指针指定了成员而非成员所属的对象,只有当解引用成员指针时,我们才提供对象信息. 2.和普通的函数指针类似,如果成员存在重载的问题,则我们必须显示地声明函数类型以明确指出我们想要使用的是哪个函数.和使用指向数据成员的指针一样,我们使用 .* 或者 ->*运算符作用于指向成员函数的指针. class test { public: void Add(int){} void Add(long){} void get() {}

类成员指针

数据成员指针 成员指针是指可以指向非静态成员的指针,成员指针指示的是类的成员,而非类的对象.类的静态成员不属于任何对象,因此无须特殊的指向静态成员指针,指向静态成员的指针与普通的指针没有什么区别. class Screen { public: typedef std::string::size_type pos; char get_cursor() const { return contents[cursor]; } char get() const; char get(pos gt, pos

类成员的指针

ps:const对象只能调用const函数!!非const对象随便!! 成员指针只应用于类的非 static 成员.static 类成员不是任何对象的组成部分,所以不需要特殊语法来指向 static 成员,static 成员指针是普通指针. int *p = &Screen::total;    (total 是 static int total;) 例子: #include<iostream> using namespace std; class Screen{ public: st

类成员函数的指针与多态性

1 类成员函数的指针 2 类成员函数的指针数组 3 指向类成员函数的指针的指针 1 类成员函数的指针 auto func1 = &com::jia;//C++函数指针 int (com::*p)(int, int) = &com::jia;//C函数指针 1 #include <iostream> 2 3 class com 4 { 5 private: 6 int a; 7 int b; 8 public: 9 com(int x, int y) :a(x), b(y) 10

C++的继承操作---基类指针访问派生类问题---基类成员恢复访问属性问题

#include "stdafx.h" #include <iostream> #include <algorithm> using namespace std; class Base { public: int num; virtual void func() { cout<<"Do something in Base"<<endl; } }; class Derived:private Base { public:

C++中如何获取类成员的指针

 我们都知道C++ class中有三种成员函数,static(静态的),nonstatic(非静态的),virtual(虚拟的)各种成员函数的指针各有区别,以下是一个完整的例子:(注意红颜色的区别) class A { public: static void staticmember(){cout<<"static"<<endl;}   //static member void nonstatic(){cout<<"nonstatic&