类和对象的使用之对象指针-冯金伟博客园

1、对象指针的一般概念
对象指针:指向类的成员的指针。在C++中,可以说明指向类的数据成员和成员函数的指针。
对象指针遵循一般变量指针的各种规则:类名 *对象指针名;
                                            对象指针名à成员名;
对象指针在使用之前,也一定要先进行初始化,让它指向一个已经声明过的对象,然后再使用。通过对象指针,可以访问到所指向对象的公有成员。
 

2.指向对像的指针
在建立对像时,编译系统会为每一个对像分配一定的存储空间,以存放其成员,对像空间的起始地址就是
对像的指针。可以定义一个指针变量,用来存和对像的指针。如果有一个类:

class Time
{
   public:
 int hour;
        int minute;
        int sec;
        void get_time();
};
void Time::get_time()
{
   cout << hour << ":" << minute << ":" << sec << endl;
}

在此有以下语句:

Time *pt;//定义pt 为指向Time类对像的指针变量
Time t1;//定义t1为Time类对像
pt=&t1;//将t1的起始地址赋给pt

这样,pt 就是指向Time类对象的指针变量,它指向对象t1。
定义指向类对象的指针变量的一般形式为:

类名 *对象指针名;

可以通过对象指针访问对象和对象的成员。如:

*pt       pt所指向的对像,即t1
(*pt).hour      pt所指向的对象中的hour成员,即t1.hour
pt->get_time()  pt把指向的对象中的get_time函数,即t1.get_time()
(*pt).get_time()

3.指向对象成员的指针

a.指向对象数据成员的指针
定义指向对象数据成员的指针的方法与定主指向变通的指针变量的方法相同。如:
int *p;

定义指向对象数据成员的指针变量的一般形式为:

数据类型名 *指针变量名;

b.指向对象成员函数的指针

定义指向对象成员函数的指针变量的方法和定义指向变通函数的指针变量方法有所不同。
定义指向变通函数的指针变量的方法:

数据类型名  (*指针变量名)();如:
void (*p)();//p是指向void型函的指针变量

定义指向成员函的指针:

数据类型名 (类名::*指针变量名)();
使指针变量指向一个公用成员函数的一般形式为
指针变量名=&类名::成员函数名;

示例:

 1 #include <iostream>
 2 using namespace std;
 3 class Time
 4 {
 5  public:
 6   Time(int ,int ,int );
 7   int hour;
 8   int minute;
 9   int sec;
10   void get_time();
11 };
12 Time::Time(int h,int m,int s)
13 {
14  hour = h;
15  minute= m;
16  sec = s;
17 }
18 void Time::get_time()
19 {
20  cout << hour << ":" << minute << ":" << sec << endl;
21 }
22 
23 int main()
24 {
25  Time t1(10,13,56); //定义Time类对象t1
26  int *p1=&t1.hour;//定义指向整型数据的指针变量p1,并使p1指向t1.hour
27  cout << *p1 << endl;
28  t1.get_time();//调用对象t1的成员函数get_time()
29 
30  Time *p2=&t1;//定义指向Time类对象的指针变量p2,并使p2指向t1
31  p2->get_time();//调用p2所指向对象的get_time()函数
32  void (Time::*p3)();//定义指向Time类公用成员函数get_time
33  p3 = &Time::get_time;//使p3指向Time类公用成员函数get_time
34  (t1.*p3)();//调用对象t1中p3所指的成员函数
35 
36  return 0;
37 }

4、指向类的非静态成员的指针(非指向对象,而是指向对象成员)

指向对象成员的指针使用前也要先声明,再赋值,然后引用,因此首先要声明指向该对象所在类的成员的指针。注意,通过指向成员的指针也只能访问到公有成员。
语法形式:类型说明符   类名::*指针名;          //声明指向公有数据成员的指针
             类型说明符   (类名::*指针名)(参数表);//声明指向公有函数成员的指针
对数据成员指针赋值:
             指针名 = &类名::数据成员;
此时还不能通过指针访问变量。类的声明只确定了各个数据成员的类型、所占内存大小以及它们的相对位置,在声明时并不为数据成员分配具体的地址。因此经上述赋值之后,只是说明了被赋值的成员指针式专门用于指向哪个数据成员的,同时在指针中存放该数据成员在类中的相对位置,当然通过这样的指针现在并不能访问什么。
       由于类是通过对象而实例化的,在声明类的对象时才会为具体的对象分配内存空间,这时只要将对象在内存中的起始地址与成员指针中存放的相对偏移结合起来就可以访问到对象的数据成员了。
       语法形式:对象名.*类成员指针名
        或          对象指针名à*类成员指针名
       成员函数指针赋值:
                      指针名 = 类名::函数成员名;
       经过上述对成员函数指针赋值之后,还不能用指针直接调用成员函数,而是需要首先声明类的对象,因为必须要通过对象来调用非静态成员函数。
       利用指针调用成员函数:
                      (对象名.*类成员指针名)(参数表)
     或      (对象指针名à*类成员指针名)(参数表)
 
5、指向类的静态成员的指针
       类的静态成员可以用普通的指针来指向和访问。/**形式上把静态成员看成普通变量就可以**/

对象指针:在C++中,可以说明指向类的数据成员和成员函数的指针。

1. 对象指针作函数的参数

    使用对象指针作为函数参数要经使用对象作函数参数更普遍一些。因为使用对象指针作函数参数有如下两点好处:

    (1) 实现传址调用。可在被调用函数中改变调用函数的参数对象的值,实现函数之间的信息传递。

    (2) 使用对象指针实参仅将对象的地址值传给形参,而不进行副本的拷贝,这样可以提高运行效率,减少时空开销。

    当形参是指向对象指针时,调用函数的对应实参应该是某个对象的地址值,一般使用&后加对象名。下面举一例子说明对象指针作函数参数。

 1 #include <iostream.h>
 2     class M
 3     {
 4     public:
 5         M() { x=y=0; }
 6         M(int i, int j) { x=i; y=j; }
 7         void copy(M *m);
 8         void setxy(int i, int j) { x=i; y=j; }
 9         void print() { cout<<x<<","<<y<<endl; }
10     private:
11         int x, y;
12     };
13 
14     void M::copy(M *m)
15     {
16     x=m->x;
17     y=m->y;
18     }
19 
20     void fun(M m1, M *m2);
21     void main()
22     {
23     M p(5, 7), q;
24     q.copy(&p);
25     fun(p, &q);
26     p.print();
27     q.print();
28     }
29 
30     void fun(M m1, M *m2)
31     {
32     m1.setxy(12, 15);
33     m2->setxy(22,25);
34     }
35 
36     输出结果为:
37     5,7
38     22,25

  从输出结果可以看出,当在被调用函数fun中,改变了对象的数据成员值[m1.setxy(12, 15)]和指向对象指针的数据成员值[m2->setxy(22, 25)]以后,可以看到只有指向对象指针作参数所指向的对象被改变了,而另一个对象作参数,形参对象值改变了,可实参对象值并没有改变。因此输出上述结果。

2. 对象引用作函数参数

    在实际中,使用对象引用作函数参数要比使用对象指针作函数更普遍,这是因为使用对象引用作函数参数具有用对象指针作函数参数的优点,而用对象引用作函数参数将更简单,更直接。所以,在C++编程中,人们喜欢用对象引用作函数参数。现举一例子说明对象引用作函数参数的格式。

 1 #include <iostream.h>
 2     class M
 3     {
 4     public:
 5         M() { x=y=0; }
 6         M(int i, int j) { x=i; y=j; }
 7         void copy(M &m);
 8         void setxy(int i, int j) { x=i; y=j; }
 9         void print() {cout<<x<<","<<y<<endl; }
10     private:
11         int x, y;
12     };
13 
14     void M::copy(M &m)
15     {
16         x=m.x;
17         x=m.y;
18     }
19 
20     void fun(M m1, M &m2);
21 
22     void main()
23     {
24         M p(5, 7), q;
25         q.copy(p);
26         fun(p, q);
27         p.print();
28         q.print();
29     }
30 
31     void fun(M m1, M &m2)
32     {
33         m1.setxy(12, 15);
34         m2.setxy(22, 25);
35     }

该例子与上面的例子输出相同的结果,只是调用时的参数不一样。

3.this指针

  this指针是一个隐含于每一个类的成员函数中的特殊指针,它用于指向正在被成员函数操作的对象。实际过程是,当通过一个对象调用成员函数时,系统先将该对象的地址赋给this指针,然后调用成员函数,成员函数对对象的数据成员进行操作时,就隐含使用了this指针。/**难怪:在成员函数之外无法访问数据成员,找不到对象呀!(当然中间的private,protected另作谈论**/

    当对一个对象调用成员函数时,编译程序先将对象的地址赋给this指针,然后调用成员函数,每次成员函数存取数据成员时,由隐含作用this指针。而通常不去显式地使用this指针来引用数据成员。同样也可以使用*this来标识调用该成员函数的对象。下面举一例子说明this指针的应用。

 1 #include <iostream.h>
 2     class A
 3     {
 4     public:
 5     A() { a=b=0; }
 6     A(int i, int j) { a=i; b=j; }
 7     void copy(A &aa);    //对象引用作函数参数
 8     void print() {cout<<a<<","<<b<<endl; }
 9     private:
10     int a, b;
11     };
12 
13     void A::copy(A &aa)
14     {
15     if (this == &aa) return;    //这个this是操作该成员函数的对象的地址,在这里是对象a1的地址
16     *this = aa;    //*this是操作该成员函数的对象,在这里是对象a1。
17             //此语句是对象aa赋给a1,也就是aa具有的数据成员的值赋给a1的数据成员
18     }
19 
20     void main()
21     {
22     A a1, a2(3, 4);
23     a1.copy(a2);
24     a1.print();
25     }

  版权所有,转载请注明转载地址:http://www.cnblogs.com/lihuidashen/p/4383038.html