`

C++中的指针

    博客分类:
  • C++
阅读更多

C++的指针有4种:指向数据,指向函数,指向成员数据和指向成员函数;为什么不分两种,指向数据和指向函数,这个前2种和后2种不能一对一。可以这么分,指向非成员和指向成员,指向成员的简称成员指针。以下一一说明。

 

 

1,指向数据的指针

非常简单。例如:

int a = 100;
int *p = &a;
cout<<*p<<endl;

2,指向函数的指针

函数名可以看成是一个单身函数对象,取值后是函数的入口地址,如:

void foo(int a)
{
}

foo看成是一个类型是void (int)的单身对象,但是对名字foo取值后,它会退化成相应的指针类型void (*)(int)。注意那个括号不能少。当然如果对foo取地址也是这个类型(取两次?没考虑过~~哇靠~太绝了吧)。

所以指向函数的指针,申明起来比较怪,像这样:

void (*pf)(int) = &foo;

申明一个类型是void (*)(int)的函数指针pf,并初始化为&foo,这里的函数参数类型形式和返回类型要和foo的声明一致。再多一个例子吧:

int foo2(float a,double b)
{
    return 0;
}

int (*pf2)(float,double) = &foo2;

函数指针的使用,两种方式:

(*pf)(100);

即,先引用*,打括号,再传实参调用,或者直接,pf(100)。

函数指针的意义:一个函数可以看成是一个策略,对于一个问题,可以采用不同的策略和方法,这种对策略的选择推迟到运行期,即用一个变量保存起来,在程序跑起来的时候,决定使用什么策略,其本质即是动多态,对一个函数的调用延迟到运行时决定。

3,指向成员数据的指针

在要说成员指针之前,要先明确一个概念:名称的受限。C++有一套自己的名称查找机制,一个名称可以是一个类名,对象名,函数名等。受限是指是否用::,->,.中的一种符号作用。

看一般的成员数据访问:

struct A{int a;};

A a;
A* p=&a;
cout<<a.a<<p->a<<endl;

当然类A的定义和下面三条语句不是在一起的,a.a是正确的名称,第一个a没有受限,指对象a,第二个a受限了,是在一个前提下进一步指成员A::a,这里就是a的成员A::a。再举个例子:

struct A
{
    A(int a)
    {
        this->a=a;
    }
    int a;
};

受限的名称要受前面的名称作用,如果a没有确定,那a.a就不能确定,确定a可以使用指针,当然确定a.a也可以使用指针,即成员指针。题外话,在模板中如果一个名称被一个包含模板参数的表达式限制,即被一个不确定的东西限制,那它的绑定将延迟到模板的实例化时,如果表示类型,要前加typename,如果表示成员模板,要在.和->后加template。比如一个模板类(或者叫类模板)中的成员函数中的this指针,实际上它的类型是不确定的,如:

template<typename T>
class V
{
};

的this是V<T>*类型的。

转到正题。成员指针实质上是成员数据的偏移。像这样定义:

int A::*p;

它不能直接指向一个数据,因为它必须要是一个受限的名称,它只能指向一个类的成员,它像这样赋值和初始化:

p=&A::a;

它不能单独使用,因为单独使用的时候是非受限的,要先定义一个A的对象,再限制使用:

A a(100);
cout<<a.*p<<endl;

它必须放在一个限制式的右边。用几个例子来说明一下:

A a(100);
A *p1=&a;
int A::*p2=&A::a;
cout<<p1->*p2<<endl; //实际访问了a.a

另外一个含内套类的复杂一些的例子:

struct A
{
    A(int _a,int _b): a(_a),b(_b)
    {
    }
    struct B
    {
        B(int _b): b(_b)
        {
        }
        int b;
    };
    int a;
    B b;
};

int main()
{
    A a(1,2);
    A *p1=&a;
    A::B A::*p2=&A::b;
    int A::B::*p3=&A::B::b;
    cout<<*p1.*p2.*p3<<endl;
    return 0;
}

4,指向成员函数的指针

如果(3)弄清楚了这个也应该很明白了,成员函数默认绑定this指针,即成员函数名也是一个受限的名称。它的定义和一般的函数定义类似,只是在指针前加上一个类名和::。

struct A
{
    A(int a)
    {
        this->a=a;
    }
    void foo(int)
   {
   }
    int a;
};

A a;
void (A::*pf)(int) = &A::foo;
(a.*pf)(100);// 相当于调用a.foo(100)

使用和(3)一样,完了再括起来传参调用函数,这个时候不能使用另外一种调用形式了,即不能这样调用:a.pf(100),即使pf是A的成员数据也不可以,例如:

struct A
{
    A(): pf(&A::foo1) {}
    A(int): pf(&A::foo2) {}
    void foo1(int)
    {
        cout<<"foo1 is called"<<endl;
    }
    void foo2(int)
    {
        cout<<"foo2 is called"<<endl;
    }
    void foo()
    {
        (this->*pf)(0);
    }
    void (A::*pf)(int);
};

int main()
{
    A a,b(0);
    a.foo();// 输出 foo1 is called
    b.foo();// 输出 foo2 is called
    return 0;
}

为什么不能默认使用pf呢?pf是A的成员,按理说会有隐含的this->在前面,如果foo()里换成:(*pf)(0);,会编译错误。原因是,pf是成员,但*pf不是,如果像后者那样调用,它相当于:(*(this->pf))(0)。直接引用了成员指针。

另外,static成员数据和成员函数不能用成员指针,它们不认为是对象的一部分,它们可以直接用一般指针访问,当然它们也是受限的名称,但是受一个类名限制和对象名无关。

分享到:
评论

相关推荐

    c++中指针的详细介绍

    在C++编程语言中,指针是一个至关重要的概念,它为程序员提供了对内存直接操作的能力,使得高级编程技巧如动态内存分配、数据结构实现、函数指针等成为可能。本书《C++中指针的详细介绍》针对初学者,旨在帮助他们...

    C++中指针的使用艺术

    ### C++中指针的使用艺术 #### 一、引言 C++作为一种高效且功能强大的编程语言,广泛应用于各种领域,从系统编程到游戏开发,再到高性能计算。其中,指针是C++中一项核心特性,它允许程序员直接操纵内存,从而实现...

    C++指针详解

    从给定的文件标题“C++指针详解”和描述“关于C++中指针的详细解释,写的很好有助于理解”,以及部分展示的内容来看,本文旨在深入探讨C++语言中的指针概念及其与数组的关系,尤其关注于指针的声明、初始化、赋值...

    C++指针 数组 内存释放.docx

    C++指针数组内存释放 C++指针是一种基本变量,包含一个实际的数据,该数据代表一个可以找到实际信息的内存地址。指针是C++编程中非常重要的概念,许多程序和思想依靠指针作为他们设计的基础。 定义指针变量 定义...

    c++数组指针ppt

    C++数组指针是C++编程语言中两个重要的概念,数组和指针都是C++编程的基础概念。理解数组和指针的关系和使用方法是C++编程的关键。 一、指针的定义与使用 指针是C++中的一种数据类型,它是一个变量,它存储了内存...

    C/C++ 函数指针的意义,函数指针的用法

    在C/C++编程中,函数指针是一种高级特性,它允许程序员处理函数的方式如同处理变量一般灵活。理解函数指针的意义及其用法,对于提升代码的可扩展性和灵活性至关重要。 #### 1. 函数指针的基本概念 在C/C++中,函数...

    C++双指针示例

    在C++编程中,双指针是一种非常常见且强大的技术,尤其在处理数组、链表以及其他数据结构时。双指针的基本思想是设置两个指针,一个从数组或数据结构的头部开始,另一个从尾部开始,然后逐渐靠近,直到找到特定条件...

    c++智能指针的创建

    C++中的指针是很麻烦的,难以管理和释放内存。为了减少问题的出现,现在有很多技巧去减少问题的出现。智能指针是其中一种解决方案。 智能指针是一种特殊的类,它可以模拟指针的行为,但同时也可以自动释放内存。它...

    C++指针介绍.ppt

    C++指针介绍.ppt C++指针介绍.ppt C++指针介绍.ppt C++指针介绍.ppt C++指针介绍.ppt C++指针介绍.ppt C++指针介绍.ppt C++指针介绍.ppt C++指针介绍.ppt C++指针介绍.ppt C++指针介绍.ppt C++指针介绍.ppt C++指针...

    c++学习笔记(c++ 线程 指针 调试 编码)

    本学习笔记主要涵盖了C++中的几个关键主题:线程、指针、调试以及编码实践。 首先,关于C++的线程:在多核处理器的时代,线程成为了实现并行处理和提高程序性能的重要手段。C++11引入了标准库中的`&lt;thread&gt;`,使得...

    C++指针与动态分配内存new关键字专题

    在C++中,指针是一种基础的数据类型,它存储的是其他变量或函数的内存地址。通过指针,可以实现对变量的间接访问和操作。掌握指针的使用对于深入学习C++至关重要,特别是当涉及到动态内存分配时。本文将详细介绍C++...

    指针在C与C++:深入比较与应用差异

    指针是C语言和C++语言中的核心概念,它们提供了对内存的直接操作能力。尽管C和C++在很多方面相似,但它们在指针的使用上存在一些关键差异。本文将深入探讨C语言和C++中指针的使用差异,分析它们的相似之处和不同之处...

    C++智能指针测试代码

    C++ 7种智能指针测试代码

    C++指针变量使用详细说明

    很好的ppt,大约30多页,看完后让你彻底明白,C++中指针的使用。。

    C++指针及句柄

    ### C++指针及句柄详解 #### 一、引言 在计算机编程领域,特别是对于像C++这样的强类型语言来说,理解指针是非常重要的。指针是一种特殊的数据类型,它存储的是其他数据的内存地址。掌握指针的使用不仅能够帮助...

    C/C++中多级指针的线性剖析

    C/C++中的多级指针是编程中一个复杂而强大的概念。它允许程序员创建指向其他指针的指针,这种结构在处理数据结构如数组和动态内存管理时特别有用。为了深入理解多级指针,我们首先需要理解指针的基础概念,然后逐步...

    C++指针概述和初步应用

    ### C++指针概述与初步应用 #### 一、引言 C++作为一种广泛使用的编程语言,其强大的功能和灵活性很大程度上得益于指针这一概念。本文将深入探讨C++中的指针基础知识及其基本用法,并通过实例来帮助读者更好地理解...

Global site tag (gtag.js) - Google Analytics