類和對象的使用之對象指針

一、對象指針的通常概念
對象指針:指向類的成員的指針。在C++中,能夠說明指向類的數據成員和成員函數的指針。
對象指針遵循通常變量指針的各類規則:類名 *對象指針名;
                                            對象指針名à成員名;
對象指針在使用以前,也必定要先進行初始化,讓它指向一個已經聲明過的對象,而後再使用。經過對象指針,能夠訪問到所指向對象的公有成員。
 

2.指向對像的指針
在創建對像時,編譯系統會爲每個對像分配必定的存儲空間,以存放其成員,對像空間的起始地址就是
對像的指針。能夠定義一個指針變量,用來存和對像的指針。若是有一個類:html

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

在此有如下語句:ios

Time *pt;//定義pt 爲指向Time類對像的指針變量
Time t1;//定義t1爲Time類對像
pt=&t1;//將t1的起始地址賦給pt

這樣,pt 就是指向Time類對象的指針變量,它指向對象t1。
定義指向類對象的指針變量的通常形式爲:編程

類名 *對象指針名;函數

能夠經過對象指針訪問對象和對象的成員。如:ui

*pt pt所指向的對像,即t1 (*pt).hour pt所指向的對象中的hour成員,即t1.hour pt->get_time() pt把指向的對象中的get_time函數,即t1.get_time() (*pt).get_time()

 

3.指向對象成員的指針this

a.指向對象數據成員的指針
定義指向對象數據成員的指針的方法與定主指向變通的指針變量的方法相同。如:
int *p;spa

定義指向對象數據成員的指針變量的通常形式爲:指針

數據類型名 *指針變量名;code

b.指向對象成員函數的指針htm

定義指向對象成員函數的指針變量的方法和定義指向變通函數的指針變量方法有所不一樣。
定義指向變通函數的指針變量的方法:

數據類型名  (*指針變量名)();如:
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 }

 

四、指向類的非靜態成員的指針(非指向對象,而是指向對象成員)

指向對象成員的指針使用前也要先聲明,再賦值,而後引用,所以首先要聲明指向該對象所在類的成員的指針。注意,經過指向成員的指針也只能訪問到公有成員。
語法形式:類型說明符   類名::*指針名;          //聲明指向公有數據成員的指針
             類型說明符   (類名::*指針名)(參數表);//聲明指向公有函數成員的指針
對數據成員指針賦值:
             指針名 = &類名::數據成員;
此時還不能經過指針訪問變量。類的聲明只肯定了各個數據成員的類型、所佔內存大小以及它們的相對位置,在聲明時並不爲數據成員分配具體的地址。所以經上述賦值以後,只是說明了被賦值的成員指針式專門用於指向哪一個數據成員的,同時在指針中存放該數據成員在類中的相對位置,固然經過這樣的指針如今並不能訪問什麼。
       因爲類是經過對象而實例化的,在聲明類的對象時纔會爲具體的對象分配內存空間,這時只要將對象在內存中的起始地址與成員指針中存放的相對偏移結合起來就能夠訪問到對象的數據成員了。
       語法形式:對象名.*類成員指針名
        或          對象指針名à*類成員指針名
       成員函數指針賦值:
                      指針名 = 類名::函數成員名;
       通過上述對成員函數指針賦值以後,還不能用指針直接調用成員函數,而是須要首先聲明類的對象,由於必需要經過對象來調用非靜態成員函數。
       利用指針調用成員函數:
                       (對象名.*類成員指針名)(參數表)
     或      (對象指針名à*類成員指針名)(參數表)
 
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

相關文章
相關標籤/搜索