case1
Java:
class A {
public A() {
System.out.println("A~~~~~~~~~~~~~~~~~~~~~~~");
}
}
class B {
public B() {
System.out.println("B~~~~~~~~~~~~~~~~~~~~~~~");
}
A a;
}
C++:
class A{
public:
A(){
cout<<"A~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
}
};
class B{
public:
B(){
cout<<"B~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
}
A a;
};
C++輸出為:
A~~~~~~~~~~~~~~~~~~~~~~~
B~~~~~~~~~~~~~~~~~~~~~~~
Java輸出為:
B~~~~~~~~~~~~~~~~~~~~~~~
這個(gè)例子體現(xiàn)了C++在Java的細(xì)節(jié)差異:
Java:
- 在Java中primitive types為值語義,
- 非class 對象都是對象語義/引用語義,Java只能通過以下方式進(jìn)行實(shí)例化
- new
- 使用反射,newInstance
- 對象的clone方法
- 某些類提供的工廠方法或通過反序列化等
而顯然上面的代碼中a并沒有實(shí)例化,只是個(gè)空指針。
C++:
上面代碼對Java來說答案非常簡單,對C++代碼很多人第一直覺B的構(gòu)造函數(shù)沒有什么特別,只是打印B,那為什么會輸出A的信息呢?
原因是此時(shí)如果類有多個(gè)成員變量,那么構(gòu)造函數(shù)會按照成員變量聲明的順序來調(diào)用成員變量的默認(rèn)構(gòu)造函數(shù)。
case2
Java:
class A {
public A() {
System.out.println("A~~~~~~~~~~~~~~~~~~~~~~~");
}
}
class B extends A{
public B() {
//super(); 不顯示寫super(),也會調(diào)用父類構(gòu)造
System.out.println("B~~~~~~~~~~~~~~~~~~~~~~~");
}
}
C++:
class A{
public:
A(){
cout<<"A~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
}
};
class B : A{
public:
B(){
cout<<"B~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
}
};
在繼承鏈上的構(gòu)造函數(shù),C++與Java的表現(xiàn)都是一樣的,都是先構(gòu)造父類,然后構(gòu)造子類。
case3
委托構(gòu)造,在C++11前構(gòu)造函數(shù)不能相互調(diào)用,而在C++11中提供了委托構(gòu)造(構(gòu)造函數(shù)可以調(diào)用其他構(gòu)造函數(shù))的支持。在Java天然提供支持
Java:
class B extends A{
public B() {
System.out.println("B~~~~~~~~~~~~~~~~~~~~~~~");
}
public B(int x) {
this();
System.out.println(x);
}
}
C++:
class B:A{
public:
B(){
cout<<"B~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
}
B(int x) : B(){
cout<<x<<endl;
}
};
WalkeR_ZG