1. 程式人生 > >String str = new String("content") 建構函式有沒有返回值?new關鍵字到底在物件初始化中做了什麼?

String str = new String("content") 建構函式有沒有返回值?new關鍵字到底在物件初始化中做了什麼?

看到String str = new String("content")時想到一個問題:在我印象裡,建構函式時沒有返回值的,那麼建立的物件是如何賦值的呢?有沒有方法確定知道建構函式有沒有返回呢?

建構函式時沒有返回值的,賦值因為new關鍵字。

new的內部是呼叫了一個叫void * operator new(size_t size)的函式,operator new和malloc類似,他向系統申請一塊空間,這塊空間沒有型別也沒有被初始化,new在拿到這塊空間後把這塊空間型別化,初始化,也就是說在呼叫建構函式初始化之前這個物件就已經存在了,new在初始化完之後將這塊空間的地址返回去了,並不是建構函式返回的。

當我們使用關鍵字new在堆上動態建立一個物件時,它實際上做了三件事:獲得一塊記憶體空間、呼叫建構函式、返回正確的指標。當然,如果我們建立的是簡單型別的變數,那麼第二步會被省略。假如我們定義瞭如下一個類A:

class A
{
   int i;
public:
   A(int _i) :i(_i*_i) {}
   void Say()  { printf("i=%d\n", i); }
};
//呼叫new:
A* pa = new A(3);

那麼上述動態建立一個物件的過程大致相當於以下三句話(只是大致上):

A* pa = (A*)malloc(sizeof(A));
pa->A::A(3);
return pa;

雖然從效果上看,這三句話也得到了一個有效的指向堆上的A物件的指標pa,但區別在於,當malloc失敗時,它不會呼叫分配記憶體失敗處理程式new_handler,而使用new的話會的。因此我們還是要儘可能的使用new,除非有一些特殊的需求。 

 

 

 

構造方法是一種特殊的方法,具有以下特點。 
(1)構造方法的方法名必須與類名相同。 
(2)構造方法沒有返回型別,也不能定義為void,在方法名前面不宣告方法型別。 
(3)構造方法的主要作用是完成物件的初始化工作,它能夠把定義物件時的引數傳給物件的域。 
(4)構造方法不能由程式設計人員呼叫,而要系統呼叫。 
(5)一個類可以定義多個構造方法,如果在定義類時沒有定義構造方法,則編譯系統會自動插入一個無引數的預設構  造器,這個構造器不執行任何程式碼。 
(6)構造方法可以過載,以引數的個數,型別,或排列順序區分。 
 

A a=new A;

A a=new A();

new 一個類或者結構體的話,實際上就是呼叫了他的無引數建構函式。
加上括號,指名了呼叫類的無引數的建構函式 ;括號內加引數的話,就是呼叫其他帶引數的類的構造函數了。
帶不帶括號取決於類的建構函式。如果建構函式為有引數,那麼new 後的括號中要有相應的引數。
如果是無參的建構函式,那麼有無括號都行。總結就是()內有引數,則必須帶。其他隨意。