指针(三)对象指针

对象指针

一、对象指针的一般概念

  • 和基本类型的变量一样,每个对象在初始化之后都会在内存中占有一定的空间
  • 对于一个对象来说,既可以通过对象名进行访问,也可以通过对象的地址来访问一个对象
  • 一个对象包含数据成员和成员函数,但对象所占据的内存空间只是用于存放数据成员的,

函数成员不在每一个对象中存储副本。

对象遵循一般变量指针的各种规则,声明对象指针的一般语法形式为:

类目名 *对象指针名;

//假如现在已经有个Point的类
Point *ptr;  //声明point类的对象指针变量ptr
Point point; //声明point类的对象point
ptr=&point;  //将对象point的地址赋给对象指针ptr

对于对象指针来说,除了一般的使用之外,还有一种方便地访问对象地成员的方法:

对象指针名 *->*成员名

这种形式与:"(*对象名).成员名 " 的访问形式是等价的

class Point//定义一个Point的类
{
public:
    Point(int x=0,int y=0):x(x),y(y){}
    int getX() const {return x;}
    int getY() const {return y;}
private:
    int x,y;
};
int main()
{
    Point  A(3,4);  //声明一个对象A
    Point *p=&A;	
    //p为Point的一个对象指针,指向对象A;
    //通过对象名访问
    cout<<   A.getX()<<endl;
    //通过指针访问(一般的方法)
    cout<<(*p).getX()<<endl;
    //通过指针访问(特殊的方法)
    cout<<  p->getX()<<endl;
}

拓展:

在之前的C++课程教材上曾用过这一个程序案例:

class Fred;		//前向引用声明
class Barney
{
	Fred x;     //错误:类Fred的定义尚不完善
};
class Fred
{
	Barney y;	//正确:类Barney在此类之前已经定义
}

这个错误在之前似乎是没有办法解决的,但是运用指针,成为一下形式,语法上就可以通过。

class Fred;//前向引用声明
class Barney
{
	Fred *x;  //正确:类Barney中声明一个类Fred的
              //指针(不是对象),这是允许的。
};
class Fred
{
	Barney y;//正确:类Barney在此类之前已经定义
}

二、this指针

this 指针是一个隐含于每一个类的非静态成员函数中的特殊指针(包含构造函数和析构函数),他用于指向正在被成员函数操作的对象。

细节:

  • this指针实际上是类成员函数的一个隐含参数。在成员函数开始执行前构造的,在成员的执行结束后清除。
  • 在调用类的成员函数时,目的对象的地址会自动作为该参数的值,传递给被调用的成员函数,这样被调函数就能够通过this指针来访问目的对象的数据成员。
  • 对于类成员函数的调用时,每次对成员函数的调用都存在一个目的对象,this指针就是指向这个目的对象的指针。
  • 当通过一个对象调用成员函数进行操作时,系统先将该对象的地址通过该参数传递给成员函数,成员函数对对象的数据成员进行操作时,就隐含使用了this指针。

可能看的有点懵,那就直接上代码!

class Point//定义一个Point的类
{
public:
    Point(int x=0,int y=0):x(x),y(y){}
    int getX() const {return x;}
    //this指针在调用时会被当做参数传进来指明这个对象。
    //在调用的时候 实际上的形式
    //int getX() const{return this->x;}
    //只是把“this->”隐藏了
    int getY() const {return y;}
private:
    int x,y;
};
int main()
{
    Point  A(3,4);  //声明一个对象A
	A.getx();
    //A对象的this指针就会以隐含参数的形式给getX()函数,
    //进而把使得该函数可以对A的数据成员进行操作。
}

注意:

  • this是一个指针常量,对于常成员函数来说,this同时又是一个指向常量的指针。

这里的const与指针可以参考之前指针(一)里面的2.2。

  • this指针不能在静态函数中使用

因为静态函数表示了整个类范围的意义,而this指针却实实在在的对于一个对象。

拓展:

当局部作用域中声明了与类成员同名的标识符时,对该标识符的直接引用代表的时局部作用域中声明的标识符,这是为了访问该类的成员,可以通过this指针。

class Point//定义一个Point的类
{
public:
    Point(){};
    int getX() 
    {
        int x;//声明一个局变量的x;
        x=1;
        this->x=2;//对类成员同名的x的访问
        return x;
   //注意此时return返回的时局部变量的x
   //调用getX()将返回的值是:1
   //如果想返回类成员同名的x
   //就要用this指针,将return语句改为:
        //return this->x;
   //再调用getX()将返回的值是:2
    }
private:
    int x=0,y=0;
};

三、指向类的非静态成员函数的指针

类的成员自身也是一些变量、函数或者对象等,因此也可以直接将它们的地址存放到一个指针变量中,这样就可以通过指针直接指向对象的成员,进而通过这些指针访问对象的成员。

声明指针的一般语法形式:

1. 声明指向数据成员的指针

类型说明符 类名:: * 指针名;

2. 声明指向成员函数的指针

类型说明符 (类名:: * 指针名)(参数表);

对数据成员指针赋值的一般语法形式:

指针名 =&类名::数据成员名;

利用指针调用类的成员函数:

(对象名.* 类成员指针名)(参数表)

class Point//定义一个Point的类
{
public:
    Point(){};
    int getX() {return x;}
    int getY() {return y;}
    int num=3;
private:
    int x=0,y=0;
};
int main()
{
    Point A;
    //声明指向Point类数据成员的指针
    int Point::*p;
    //将Point类的数据成员地址赋给指针。
    p=&Point::num;
    //使用
    cout<<A.*p<<endl;//或者
    //注意要保证num的可以访问到
    //x的数据成员是私有的,则无法访问
	//声明指向函数成员的指针
    int (Point::*ptr)();//注意形式要和所指向的函数声明形式一样
    //将Point类的数据成员地址赋值给指针
    ptr=&Point::getX;//函数名即为函数的地址
    cout<<(A.*ptr)();//使用时,注意和声明时的形式保持一致
}

四、指向类的静态成员的指针

对类的静态成员的访问是不依赖于对象的,因此可以用普通的指针来指向和访问静态成员。

class A//定义一个简单的A类
{
public:
    static void print()
    {cout << x << endl;}
    int gety() { return y; }
    static int x;
    int y;
};
int A::x=1;
int main()
{
    int* p1 = &A::x;
    int A::* p2 = &A::y;//对比 非静态;
    void (* ptr1)() = &A::print;
    int (A:: * ptr2)() = &A::gety;//对比 非静态的;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星空丶star

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值