java 賦值運算子、拷貝初始化和this指標

來源:互聯網
上載者:User

java 賦值運算子、拷貝初始化和this指標

   1)首先區別什麼是賦值,什麼是初始化。

  2)程式中重載採用了引用傳遞,原因:①眾所周知,用值傳遞的參數將在要傳遞的函數內產生一個副本,沒有例外。如果這個對象很大,則副本就會浪費汗多空間。②在某些情況下可能想記錄對象的數目。如果編譯器在使用賦值運算子時,每次產生一個額外的對象,這樣就可能見到比醫學多得多的對象。而引用傳遞有助於避免建立過多的對象。

  3)return alpha(data); 傳回值是重載函數所在的對象的一個副本,而不是同一個對象。返回的值可使它將運算子=串聯起來:a3=a2=a1;

  4) 然而alpha operator = (alpha& a)中值的返回與值的參數一樣的缺點:浪費記憶體空間。但是使用引用來返回函數的值如alpha& operator = (alpha& a) 這樣行嗎?

  回答是不行的:在函數內部建立的非static的局部變數,在函數返回時即被銷毀,引用所返回的值,僅僅是實際希望傳回值得地址,是沒有意義的,甚至會出現嚴重錯誤。(在這裡我們可以用this指標解決這個問題,後文會解釋)

  注意:賦值運算子是唯一一個不能繼承的運算子。如果在基類重載了賦值運算子,那麼在任何衍生類別中都不能再重載同一函數。

 代碼如下  

#include<iostream>
using namespace std;
class  alpha
{
public:
 alpha():data(0) {}       //沒有參數的建構函式
 alpha(int d):data(d) {}  //一個參數的建構函式
 void diplay()            //顯示資料
 {
  cout<<data<<endl;
 }
 alpha(alpha& a)          //重載拷貝建構函式
 {
  data=a.data;
  cout<<"copy constructor invoked! "<<endl;
 }
 alpha operator = (alpha& a) //重載賦值運算子
 {
  data=a.data;
  cout<<"assignment operator invoked! "<<endl;
  return alpha(data);  //單參數的建構函式
 }
private:
 int data;
};
int main()
{
 alpha a1(32);

 alpha a2;     //無參數建構函式
 a2=a1;        //賦值運算子
 a2.diplay();

 alpha a3=a1;  //拷貝建構函式
 a3.diplay();

 alpha a4(a1);  //拷貝建構函式
 a4.diplay();

 return 0;
}

  .看函數的幾種情況

  1)函數參數

  view sourceprint?void func(alpha); //以值傳遞對象

  func(a1); //函數調用

  這時拷貝建構函式將會被調用來建立一個對象a1的副本,並將副本交給函數func()操作。(當然引用或者指標就不會調用拷貝建構函式)

  2)函數傳回值

  view sourceprint?alpha func() //函式宣告

  a2=func() //函數調用

  在這裡:首先,程式調用拷貝建構函式來穿件一個func()傳回值的副本;

  然後,這個值再被賦給a2(調用賦值運算子)。

  3)拷貝建構函式為alpha(alpha& a) ,為什麼不是alpha(alpha a)的形式?

  答:拷貝建構函式必須使用引用,否則會報告記憶體溢出。(因為如果參數用值來傳遞,就需要建立一個該值的副本。如何棄置站台呢?使用拷貝建構函式,但是原函數本來就是要定義拷貝建構函式,這樣不斷調用自己你說會有什麼結果!~)

  二、this指標

  每一個對象的成員函數都可以訪問一種神奇的指標,即指向該對象本身的this指標,因而在任何對象中都可找到所屬對象的自身地址。

 代碼如下  

#include<iostream>
using namespace std;
class  alpha
{
public:
 alpha():data(0) {}       
 alpha(int d):data(d) {}  
 void display()            
 {
  cout<<data<<endl
   <<this->data<<endl;
 }
 //alpha operator = (alpha& a) //重載賦值運算子
 //{
 // data=a.data;
 // cout<<"assignment operator invoked! "<<endl;
 // return alpha(data);  //單參數的建構函式
 //}
 alpha& operator = (alpha& a) //重載賦值運算子
 {
  data=a.data;
  cout<<"assignment operator invoked! "<<endl;
  return *this;     //通過this指標傳回值
 }
private:
 int data;
};
int main()
{
 alpha a1(37);
 a1.display();  //直接輸出和this->data的輸出結果是一樣的
 alpha a2,a3;
 a3=a2=a1;    //調用賦值運算子
 cout<<"a2=";a2.display();
 cout<<"a3=";a3.display();
 return 0;
}

  注意執行個體中的:使用this指標傳回值。(從成員函數和重載運算子傳回值,this指標是一個更實用的用法)

  1)this指標指向的是該成員函數所屬的對象,所以*this就是這個對象本身。通常實用引用和this指標從重載賦值運算子返回資料,從而避免建立額外的對象。

  2)必須注意:this指標在靜態成員函數中是無效的,因為靜態成員函數不屬於任何特定的對象。

  三、dynamic_cast和typeid

  這兩個功能通常使用在有很多類都由一個基類派生的情況下。為了使動態類型轉換能夠工作,基類必須是多態的(也就是說至少包含一個虛函數)。

  1.dynamic_cast可以改變指標類型

 代碼如下  

#include<iostream>
#include<typeinfo>
using namespace std;
class Base
{
public:
 Base() {}
 virtual void vertfunc()  //要想用dynamic_cast,基類必須是多態類型
 {}
 Base(int b):ba(b){}
 void show()
 {
  cout<<"Base: ba="<<ba<<endl;
 }
protected:
 int ba;
};
class derv1:public Base
{};
class derv2:public Base
{
public:
 derv2():Base() {}
 derv2(int b,int d):Base(b),da(d) {}
 void show()
 {
  cout<<"derv2: ba="<<ba<<" da="<<da<<endl;
 }
private:
 int da;
};
bool isDerv1(Base* pUnknown)
{
 derv1* pderv1;
 if (pderv1=dynamic_cast<derv1*>(pUnknown))
  return true;
 else
  return false;
}
int main()
{
 derv1* d1=new derv1;
 derv2* d2=new derv2;
 if (isDerv1(d1))
  cout<<"d1是類derv1的一個對象"<<endl;
 else
  cout<<"d1不是類derv1的一個對象"<<endl;
 if (isDerv1(d2))
  cout<<"d2是類derv1的一個對象"<<endl;
 else
  cout<<"d2不是類derv1的一個對象"<<endl;

 Base* pbase=new Base(10);
 derv2* pderv=new derv2(22,33);
 pbase->show();pbase=dynamic_cast<Base*>(pderv); pbase->show(); //衍生類別到基類
 pbase=new derv2(34,32);
 pderv->show(); pderv=dynamic_cast<derv2*>(pbase); pderv->show();  //基類到衍生類別
 return 0;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.