~~~
①T *p =new T;
②T *p =new T();
~~~
這兩類用法不同點的總結。
1.若T為類類型,且用戶定義了構造函數,則兩種形式的效果完全相同,都會調用這個定義了的構造函數來初始化內部成員變量,但是如果此構造函數中并未對成員變量初始化,則這個時候內部的成員變量進行默認初始化——值是未定義的。
2.若T為類類型,但是用戶并沒有定義任何構造函數,則我們可以知道編譯器會為該類合成一個默認的構造函數,這個時候上述兩種形式的結果就不同了,①的類內部的成員變量這個時候執行默認初始化,其值是未定義的。但是在②中就不同了,加了括號后,p內部的成員變量會執行值初始化,即以0的形式進行初始化(整數就為0,bool就為false,string 就為空)
3.若T為內置類型,則①的形式中*p的值為未定義的,②中進行值初始化如上。
下面針對上面各種情況進行編程測試。
1.顯示定義構造函數,但構造函數并不對成員變量進行初始化,則無論①②都輸出的a都是未定義的值。
~~~
class Test{
public:
Test(){
printf("constructor\n");
}
int getA()const{
return a;
}
private:
int a;
};
int main(){
Test *pta = new Test;
Test *ptb = new Test();
printf("a : %d\n", pta->getA());
printf("a : %d\n", ptb->getA());
return 0;
}
~~~
2.顯示定義構造函數,并且構造函數中對成員變量就行初始化,則①②中a都是構造后的值。
~~~
class Test{
public:
Test() : a(0){
printf("constructor\n");
}
int getA()const{
return a;
}
private:
int a;
};
int main(){
Test *pta = new Test;
Test *ptb = new Test();
printf("a : %d\n", pta->getA());//output zero
printf("a : %d\n", ptb->getA());//output zero
return 0;
}
~~~
以上兩個例子說明,只要定義了構造函數,無論new的時候加不加括號,都會調用自身已有的構造函數。
3.類中不定義任何構造函數,而使用編譯器合成的默認構造函數。
~~~
class Test{
public:
int getA()const{
return a;
}
private:
int a;
};
int main(){
Test *pta = new Test;
Test *ptb = new Test();
printf("a : %d\n", pta->getA());//undefined value a->default initializer
printf("a : %d\n", ptb->getA());//output zero a->value initializer
return 0;
}
~~~
4.內置類型的兩種形式。
~~~
int main(){
int *pia = new int;
int *pib = new int();
printf("%d\n", *pia);//undefined value
printf("%d\n", *pib);//ouput zero
return 0;
}
~~~