服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++学习笔记之类成员指针

C++学习笔记之类成员指针

2022-11-13 14:13Ofnoname C/C++

类成员指针时指可以指向类的非静态成员的指针,下面这篇文章主要给大家介绍了关于C++类成员指针的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

C++的类成员指针是一种奇葩的指针。

假设现在我们要表示一个三维的点,现在有两种定义方式:

?
1
2
3
4
5
6
7
struct point1{
    int x, y, z;
};
 
struct point2{
    int c[3];
};

第一种的优点是更直观,但第二种可以方便的用for遍历三个属性。最终我选择了第一种,但是我还想弄一个遍历功能怎么办?这个时候类成员指针就排上用场了,我们可以创建一个“指向point中具体成员的指针”。

?
1
int A:: *member = &A::x;

让member指针指向A中的成员x,且类型是int,此时我们就可以通过member来访问x:

?
1
2
point1 tmp{4, 5, 6};
cout << tmp.(*member); //把member解引用,得到tmp::x,表示要访问x

所以我们定义一个数组,就可以迭代访问类里的各种int属性了

?
1
2
3
int A:: *member [] = {&A::x, &A::y, &A::z};
for (int i = 0; i < 3; ++i)
    cout << tmp.(*member[i]);

这个用途也可以放到成员函数上,构建一个函数列表,顺序调用。

这么个指针的行为跟一般的指针显然不一样,它不保存地址,而是保存一个“偏移量”,从对象地址开头到对象成员的偏移量。这玩意其实可以输出:

?
1
2
3
4
5
6
7
8
struct A{
    int a, b, c;
};
 
main() {
    printf("%d%d%d", &A::a, &A::b, &A::c); //! 输入为0, 4, 8
    //! 当然这玩意类型不是int,printf直接将他以int解析输出了,所以cout达不到效果
}

这样类成员指针的意义就很明显了,假设一个A的对象t,那么t的地址&t和a的地址&(t.a)是相等的,而&(t.b)要多出来4,&(t.c)又要多出来4。每个对象的内存构造都是一样的,这个类成员指针就是获取每个成员相对于头地址的偏移量,这样当我使用t.*member编译器就知道是头地址+4处的变量,并且是个int。

不过成员函数又不太一样了。不同对象的成员函数只有同一份程序短代码。C++不能用&(t.fun)的方式获取对象的成员函数的地址,要用取&A::fun得到函数的地址。这个当然是真地址了。

类成员指针可以用于static吗?显然不行,static成员单独存放,与类本身无关,取&A::staticmember得到的就是这个变量的正经地址。那可以用于virtual function吗?答案是可以,但是虚函数的地址无法确定,所以又变成了储存偏移量,实际上储存的是函数在虚表中的索引值。

补充:mem_fn

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#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;
}

运行

C++学习笔记之类成员指针

总结

到此这篇关于C++学习笔记之类成员指针的文章就介绍到这了,更多相关C++类成员指针内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/ofnoname/p/16172357.html

延伸 · 阅读

精彩推荐
  • C/C++C++中新手容易犯的十种编程错误汇总

    C++中新手容易犯的十种编程错误汇总

    一段C语言代码,在编译、链接和运行的各个阶段都可能会出现问题,下面这篇文章主要给大家介绍了关于C++中新手容易犯的十种编程错误的相关资料,需要的...

    IT老张4222022-02-13
  • C/C++深入解读C++中的指针变量

    深入解读C++中的指针变量

    这篇文章主要介绍了深入解读C++中的指针变量,是C语言入门学习中的基础知识,需要的朋友可以参考下...

    C++教程网4572021-03-13
  • C/C++Ubuntu中使用VS Code与安装C/C++插件的教程详解

    Ubuntu中使用VS Code与安装C/C++插件的教程详解

    这篇文章主要介绍了Ubuntu中使用VS Code与安装C/C++插件的教程详解,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴...

    tigerisland456662021-09-27
  • C/C++C、C++线性表基本操作的详细介绍

    C、C++线性表基本操作的详细介绍

    这篇文章主要给大家介绍了关于C、C++线性表基本操作的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需...

    zhen-yu9612021-10-03
  • C/C++深入学习C++智能指针之shared_ptr与右值引用的方法

    深入学习C++智能指针之shared_ptr与右值引用的方法

    智能指针的核心实现技术是引用计数,每使用它一次,内部引用计数加1,每析构一次内部的引用计数减1,减为0时,删除所指向的堆内存,今天通过本文给...

    进击的汪sir6812021-11-24
  • C/C++C++17新特性个人总结

    C++17新特性个人总结

    这篇文章主要介绍了C++17新特性个人总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小...

    岸居仔8142021-09-16
  • C/C++C语言详细讲解二分查找用法

    C语言详细讲解二分查找用法

    二分查找法,又叫做折半查找法,它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列...

    清风自在 流水潺潺7452022-11-10
  • C/C++深入理解数组指针与指针数组的区别

    深入理解数组指针与指针数组的区别

    本篇文章是对数组指针与指针数组的区别进行了详细的分析介绍,需要的朋友参考下...

    C语言教程网4672020-12-07