(1)this指針
this是一個隱含於每個類的成員函數的特殊指針,該指針是一個指向正在被某個成員函數操作的對象的指針。
當一個對象調用成員函數時,編譯程序先將對象的地址賦給this指針,也就是說,當調用成員函數時,this被初始化為被調用的成員函數所在的類實例,即對象的地址,然后調用
成員函數,每次成員函數存取數據成員時,隱含使用this指針。通常,不顯式地使用this指針。
this指針是c++實現封裝的一種機制,它將對象和該對象調用的成員函數連接在一起,在外部看來,每個對象都擁有自己的成員函數
class Myclass{ int n; public: Myclass(); //默認構造函數 Myclass(int m); //重載構造函數 void addvalue(int x); //增加x值 void disp(); //輸處數據成員n };
Myclass::Myclass(){} Myclass::Myclass(int m){ n = m; }
void Myclass::addvalue(int x){ Myclass s1; s1.n = n + x; //this指針:是一個隱含於每個類的成員函數的特殊指針,該指針是一個指向正在被某個成員函數操作的對象的指針 *this = s1; }
void Myclass::disp(){ cout<<"n=:"<<n<<endl; }
void main(){ Myclass s(10); s.disp(); s.addvalue(5); s.disp(); }
(2)對象的淺復制與深復制
#include<iostream.h> #include"string.h"
class StudClass{ int no; char *pname; public: StudClass(); StudClass(int n,char *p); ~StudClass(); void display();
StudClass & operator=(StudClass &s); };
StudClass::StudClass(){} StudClass::StudClass(int n,char *p){ no = n; pname = new char[10]; strcpy(pname,p); } StudClass::~StudClass(){ delete []pname; }
void StudClass::display(){ cout<<"學號:"<<no<<",姓名:"<<pname<<endl; } /*重載運算符“=”實現深復制 //改正方法是采用深復制,當兩個對象之間進行復制時,若復制完成后,它們不會共享任何資源(空間),其中一個對象的銷毀不會影響另一個對象 StudClass& operator=(StudClass &s){ pname = new char[10]; no = s.no; strcpy(pname,s.pname); return *this; } */ void main(){ StudClass s(10,"hubin"),t; t = s; //重大錯誤!!該語句執行的是淺復制,s和t這兩個對象的pname數據成員均指向相同的內存空間,在執行t的析構函數之后, //t.pname所指向的空間被釋放,這樣再執行s的析構函數就出錯了 cout<<"s:"; s.display(); cout<<"t:"; t.display(); }
/* 兩點說明: 1.運算符重載函數中的形參s一定采用引用類型。在該函數中並沒有改變形參s的任何值,也不需要形參s實現雙向傳遞,為什么非要采用引用類型呢? 如何不采用引用類型,在調用該函數時,需要將實參對象復制到形參s對象,而這種復制也是淺復制,並不會為形參s的pname分配所指向的空間, 導致實參和形參s對象的pname所指向的空間相同,在調用析構函數時出錯。
2.運算符重載函數時,函數的返回值是StudClass&,即對象引用,如果不引用也會出錯,這是為什么呢? 因為在執行“t=s;”時,相當於執行“t.=(s)”,如果不采用引用返回值,還需要將=(s)的返回對象復制給t對象,這種復制也是淺復制,該返回 對象和t對象的pname指向相同的空間,在兩次調用析構函數時會出錯,若用引用返回值,=(s)的返回對象和t對象共享相同的存儲空間,不會再執行 返回對象的析構函數,因而不會出錯了。
說明:在設計一個類時,如果含有指針數據成員,那么成員函數中的對象形參通常采用引用類型,否則出現錯誤
