對象指針和對象引用(this的用法)
更新時間: 2007-05-25 14:46:54來源: 粵嵌教育瀏覽量:1071
指向類的成員的指針
在C++中,可以說明指向類的數據成員和成員函數的指針。
指向數據成員的指針格式如下:
<類型說明符><類名>::*<指針名>
指向成員函數的指針格式如下:
<類型說明符>(<類名>::*<指針名>)(<參數表>)
例如,設有如下一個類A:
class A
{
public:
int fun (int b) { return a*c+b; }
A(int i) { a=i; }
int c;
private:
int a;
};
定義一個指向類A的數據成員c的指針pc,其格式如下:
int A:: *pc = &A::c;
再定義一個指向類A的成員函數fun的指針pfun,其格式如下:
int (A:: *pfun)(int) = A::fun;
由于類不是運行時存在的對象。因此,在使用這類指針時,需要首先指定A類的一個對象,然后,通過對象來引用指針所指向的成員。例如,給pc指針所指向的數據成員c賦值8,可以表示如下:
A a;
a.*pc = 8;
其中,運算符.*是用來對指向類成員的指針來操作該類的對象的。
如果使用指向對象的指針來對指向類成員的指針進行操作時,使用運算符->*。例如:
A *p = &a; //a是類A的一個對象,p是指向對象a的指針。
p ->* pc = 8;
讓我們再看看指向一般函數的指針的定義格式:
<類型說明符>*<指向函數指針名>(<參數表>)
關于給指向函數的指針賦值的格式如下:
<指向函數的指針名>=<函數名>
關于在程序中,使用指向函數的指針調用函數的格式如下:
(*<指向函數的指針名>)(<實參表>)
如果是指向類的成員函數的指針還應加上相應的對象名和對象成員運算符。
下面給出一個使用指向類成員指針的例子:
#include <iostream.h>
class A
{
public:
A(int i) { a=i; }
int fun(int b) { return a*c+b; }
int c;
private:
int a;
};
void main()
{
A x(8); //定義類A的一個對象x
int A::*pc; //定義一個指向類數據成員的指針pc
pc=&A::c; //給指針pc賦值
x.*pc=3; //用指針方式給類成員c賦值為3
int (A::*pfun)(int); //定義一個指向類成員函數的指針pfun
pfun=A::fun; //給指針pfun賦值
A *p=&x; //定義一個對象指針p,并賦初值為x
cout<<(p->*pfun)(5)<<endl; //用對象指針調用指向類成員函數指針pfun指向的函數
}
以上程序定義了好幾個指針,雖然它們都是指針,但是所指向的對象是不同的。p是指向類的對象;pc是指向類的數據成員;pfun是指向類的成員函數。因此它們的值也是不相同的。
對象指針和對象引用作函數的參數
1. 對象指針作函數的參數
使用對象指針作為函數參數要經使用對象作函數參數更普遍一些。因為使用對象指針作函數參數有如下兩點好處:
(1) 實現傳址調用。可在被調用函數中改變調用函數的參數對象的值,實現函數之間的信息傳遞。
(2) 使用對象指針實參僅將對象的地址值傳給形參,而不進行副本的拷貝,這樣可以提高運行效率,減少時空開銷。
當形參是指向對象指針時,調用函數的對應實參應該是某個對象的地址值,一般使用&后加對象名。下面舉一例子說明對象指針作函數參數。
#include <iostream.h>
class M
{
public:
M() { x=y=0; }
M(int i, int j) { x=i; y=j; }
void copy(M *m);
void setxy(int i, int j) { x=i; y=j; }
void print() { cout<<x<<","<<y<<endl; }
private:
int x, y;
};
void M::copy(M *m)
{
x=m->x;
y=m->y;
}
void fun(M m1, M *m2);
void main()
{
M p(5, 7), q;
q.copy(&p);
fun(p, &q);
p.print();
q.print();
}
void fun(M m1, M *m2)
{
m1.setxy(12, 15);
m2->setxy(22,25);
}
輸出結果為:
5,7
22,25
從輸出結果可以看出,當在被調用函數fun中,改變了對象的數據成員值[m1.setxy(12, 15)]和指向對象指針的數據成員值[m2->setxy(22, 25)]以后,可以看到只有指向對象指針作參數所指向的對象被改變了,而另一個對象作參數,形參對象值改變了,可實參對象值并沒有改變。因此輸出上述結果。
2. 對象引用作函數參數
在實際中,使用對象引用作函數參數要比使用對象指針作函數更普遍,這是因為使用對象引用作函數參數具有用對象指針作函數參數的優點,而用對象引用作函數參數將更簡單,更直接。所以,在C++編程中,人們喜歡用對象引用作函數參數。現舉一例子說明對象引用作函數參數的格式。
#include <iostream.h>
class M
{
public:
M() { x=y=0; }
M(int i, int j) { x=i; y=j; }
void copy(M &m);
void setxy(int i, int j) { x=i; y=j; }
void print() {cout<<x<<","<<y<<endl; }
private:
int x, y;
};
void M::copy(M &m)
{
x=m.x;
x=m.y;
}
void fun(M m1, M &m2);
void main()
{
M p(5, 7), q;
q.copy(p);
fun(p, q);
p.print();
q.print();
}
void fun(M m1, M &m2)
{
m1.setxy(12, 15);
m2.setxy(22, 25);
}
該例子與上面的例子輸出相同的結果,只是調用時的參數不一樣。
this指針
this指針是一個隱含于每一個成員函數中的特殊指針。它是一個指向正在被該成員函數操作的對象,也就是要操作該成員函數的對象。
當對一個對象調用成員函數時,編譯程序先將對象的地址賦給this指針,然后調用成員函數,每次成員函數存取數據成員時,由隱含作用this指針。而通常不去顯式地使用this指針來引用數據成員。同樣也可以使用*this來標識調用該成員函數的對象。下面舉一例子說明this指針的應用。
#include <iostream.h>
class A
{
public:
A() { a=b=0; }
A(int i, int j) { a=i; b=j; }
void copy(A &aa); //對象引用作函數參數
void print() {cout<<a<<","<<b<<endl; }
private:
int a, b;
};
void A::copy(A &aa)
{
if (this == &aa) return; //這個this是操作該成員函數的對象的地址,在這里是對象a1的地址
*this = aa; //*this是操作該成員函數的對象,在這里是對象a1。
//此語句是對象aa賦給a1,也就是aa具有的數據成員的值賦給a1的數據成員
}
void main()
{
A a1, a2(3, 4);
a1.copy(a2);
a1.print();
}
運行結果:
3, 4